R Function with No Return Value

R function with no return value

You need to understand the difference between a function returning a value, and printing that value. By default, a function returns the value of the last expression evaluated, which in this case is the assignment

arg <- arg + 3

(Note that in R, an assignment is an expression that returns a value, in this case the value assigned.) This is why data <- derp(500) results in data containing 503.

However, the returned value is not printed to the screen by default, unless you isolate the function's final expression on its own line. This is one of those quirks in R. So if you want to see the value:

derp <- function(arg)
{
arg <- arg + 3
arg
}

or just

derp <- function(arg)
arg + 3

R: Function without arguments and without return value?

Combining the advice from Rushabh and Gregor this would be a solution:

MyFunction = function(){
x = rnorm(10)
x <<- x^2
print("and dinosaurs are scary")
y = TRUE

return(invisible())
}

Thanks for helping!

R function not returning values

To return df, simply write return(df):

IMDBmovierating <- function(movie){
link <- paste("http://www.omdbapi.com/?t=", movie, "&y=&plot=short&r=json", sep = "")
jsonData <- fromJSON(link)
df <- data.frame(jsonData)
return(df)
}

or, even simpler in this case, omit the last assignment:

IMDBmovierating <- function(movie){
link <- paste("http://www.omdbapi.com/?t=", movie, "&y=&plot=short&r=json", sep = "")
jsonData <- fromJSON(link)
data.frame(jsonData)
}

If the last expression evaluates to a result object, as data.frame(..) does, then this gets the return object of the enclosing expression and the explicit return statement may be omitted.

edit: and remove the back-ticks before sep and after you closing parenthesis

edit2: Of course MrFlick's comment is correct: the only thing really wrong with your code are the back-ticks that probably are simply a typo here on the site. Even the assignment produces the assigned value as a result object, but it is invisible. Hence, you can assign it, but it is not automatically printed on the console.

How to create a break in function with no return value printed on console?

The invisible() modifies the attributes of an object. If you want to leave the function early, you still need to explicitly return. This put the invisible inside the return.

foo <- function() {
if (file.exists("data/some.rds") | (1 + 1 == 2)) return(invisible())
"something else"
}

Explicitly calling return in a function or not

Question was: Why is not (explicitly) calling return faster or better, and thus preferable?

There is no statement in R documentation making such an assumption.

The main page ?'function' says:

function( arglist ) expr
return(value)

Is it faster without calling return?

Both function() and return() are primitive functions and the function() itself returns last evaluated value even without including return() function.

Calling return() as .Primitive('return') with that last value as an argument will do the same job but needs one call more. So that this (often) unnecessary .Primitive('return') call can draw additional resources.
Simple measurement however shows that the resulting difference is very small and thus can not be the reason for not using explicit return. The following plot is created from data selected this way:

bench_nor2 <- function(x,repeats) { system.time(rep(
# without explicit return
(function(x) vector(length=x,mode="numeric"))(x)
,repeats)) }

bench_ret2 <- function(x,repeats) { system.time(rep(
# with explicit return
(function(x) return(vector(length=x,mode="numeric")))(x)
,repeats)) }

maxlen <- 1000
reps <- 10000
along <- seq(from=1,to=maxlen,by=5)
ret <- sapply(along,FUN=bench_ret2,repeats=reps)
nor <- sapply(along,FUN=bench_nor2,repeats=reps)
res <- data.frame(N=along,ELAPSED_RET=ret["elapsed",],ELAPSED_NOR=nor["elapsed",])

# res object is then visualized
# R version 2.15

Function elapsed time comparison

The picture above may slightly difffer on your platform.
Based on measured data, the size of returned object is not causing any difference, the number of repeats (even if scaled up) makes just a very small difference, which in real word with real data and real algorithm could not be counted or make your script run faster.

Is it better without calling return?

Return is good tool for clearly designing "leaves" of code where the routine should end, jump out of the function and return value.

# here without calling .Primitive('return')
> (function() {10;20;30;40})()
[1] 40
# here with .Primitive('return')
> (function() {10;20;30;40;return(40)})()
[1] 40
# here return terminates flow
> (function() {10;20;return();30;40})()
NULL
> (function() {10;20;return(25);30;40})()
[1] 25
>

It depends on strategy and programming style of the programmer what style he use, he can use no return() as it is not required.

R core programmers uses both approaches ie. with and without explicit return() as it is possible to find in sources of 'base' functions.

Many times only return() is used (no argument) returning NULL in cases to conditially stop the function.

It is not clear if it is better or not as standard user or analyst using R can not see the real difference.

My opinion is that the question should be: Is there any danger in using explicit return coming from R implementation?

Or, maybe better, user writing function code should always ask: What is the effect in not using explicit return (or placing object to be returned as last leaf of code branch) in the function code?

Function should not return a value if it doesn't exist in the function

If a free variable (one referred to but not defined) in a function is accessed then it looks in the environment where the function was defined and then in the parent environment of that and so on.

Use get("z", inherits = FALSE) to look for z only in the current environment or check whether it exists exists("z", inherits = FALSE) in the current environment only.

Another possibility is to always give z a value:

z <- if (length(x) && length(y) && x + y > 10) x + y

In that case z will have the value NULL if the condition is false because the default else leg is NULL. Returning NULL invisibly would be about as close as you can get to not returning a value.

xyz2 <- function(x = NULL, y = NULL) {
z <- if (length(x) && length(y) && x + y > 10) x + y
# other processing can go here
if (is.null(z)) invisible(z) else z
}
xyz2(1, 2)
xyz2(5, 9)
## [1] 14

function return in R programming language


  1. return is the explicite way to exit a function and set the value that shall be returned. The advantage is that you can use it anywhere in your function.

  2. If there is no explicit return statement R will return the value of the last evaluated expression

  3. returnValueis only defined in a debugging context. The manual states:

the experimental returnValue() function may be called to obtain the
value about to be returned by the function. Calling this function in
other circumstances will give undefined results.

In other words, you shouldn't use that except in the context of on.exit. It does not even work when you try this.

justReturnValue <- function(){
returnValue('returnValue')
2
}

This function will return 2, not "returnValue". What happened in your example is nothing more than the second approach. R evaluates the last statement which is returnValue() and returns exactly that.

If you use solution 1 or 2 is up to you. I personally prefer the explicit way because I believe it makes the code clearer. But that is more a matter of opinion.



Related Topics



Leave a reply



Submit