R – Difference of print and return in R

r

I have defined a factorial function. The script goes like this:

fac <- function(x) {
  f=1
  for (i in 1:x) {
    f = f * i
    print(f)
  }
  print(f)
}

If fac(5), then the output looks like this :

[1] 1
[1] 2
[1] 6
[1] 24
[1] 120
[1] 720
[1] 5040

But when I change the 'print(f)' parts into 'return(f)' the output is :

[1] 1

Why does this happen? Is there a difference between print and return in R?

Best Answer

Let's try by example:

fac <- function(x) {
  f=1
  for (i in 1:x) {
    f = f * i
    print(f)
  }
  print(f)
}

fac2 <- function(x) {
  f=1
  for (i in 1:x) {
    f = f * i
    print(f)
  }
  return(f)
}

fac3 <- function(x) {
  f=1
  for (i in 1:x) {
    f = f * i
    return(f)
  }
  print(f)
}

And use them:

> f1 <- fac(10)
[1] 1
[1] 2
[1] 6
[1] 24
[1] 120
[1] 720
[1] 5040
[1] 40320
[1] 362880
[1] 3628800
[1] 3628800
> f2 <- fac2(10)
[1] 1
[1] 2
[1] 6
[1] 24
[1] 120
[1] 720
[1] 5040
[1] 40320
[1] 362880
[1] 3628800
> f3 <- fac3(10)
> f1
[1] 3628800
> f2
[1] 3628800
> f3
[1] 1

print as it names implies print to the console (and return the value printed)

return only return the value and ends the function.

In the case of fac(10), the last print is the last value of f, and it returns it, as fac2(10) does with the difference it does not print it twice as there's only the print in the loop printing the value.

fac3(10) return at the first iteration, hence it does never go to the print statement and return the first value without printing anything to console.

What you can do for this is:

fixedfac <- function(x) {
  f=vector('numeric',x) # pre allocate the return vector to avoid copy while growing in the loop
  tmp=1 # use a temp var for the maths (could be avoided, but it's to keep it simple)
  for (i in 1:x) {
    tmp <- tmp * i # do the math
    f[i] <- tmp # store in result
  }
  f # return the vector with all values (we need at least this as for does not return anything).
}

Which will return a vector (return is unnecessary as a function always return the value of its last statement)

> fixedfac(10)
 [1]       1       2       6      24     120     720    5040   40320  362880 3628800