0

I want to use multiple objects created within a function with another function:

test1 <- function(x){
  y <- x + 1
  z <- x * 2
}

test2 <- function(...){
  test1(x)
  print(u <- y * z)
}

x <- 2

test2(test1)

It throws the error Error in print(u <- y * z) : object 'y' not found.

How can I reuse all objects assigned in a function without using the global assignment <<-?

yPennylane
  • 710
  • 1
  • 9
  • 24
  • return with a `list()`, like `return(list(y=y, z=z))` at the end of the function. Assign inside the second function `ret1 – RLave May 13 '19 at 08:55
  • So it's only possible to access the last assigned object in a function without using the `< – yPennylane May 13 '19 at 09:03
  • I'd avoid `< – RLave May 13 '19 at 09:21
  • If there are no explicit returns from a function, the value of the last evaluated expression is returned automatically in R. Hence, from `test1` only the last evaluated `z` is returned. Also, if you wish to return multiple things, then use explicity `return`. For example, returning `list` having `y` and `z` – Om Sao May 13 '19 at 09:21
  • @Om Prakash Sao note that in `test1` also `z` is not returned, only the last unassigned element is returned if there's no `return()`. – RLave May 13 '19 at 09:29
  • @Om Prakash Sao : So how would I access the elements `y` and `z` inside the test2 function when I used return `test1 – yPennylane May 13 '19 at 09:36
  • @yPennylane, you can't use two return inside a function, that's why you need a `list()` or `c()`, to concatenate the results. – RLave May 13 '19 at 09:39

2 Answers2

1

I'd use a simple return() with a list() or c():

test1 <- function(x){
  y <- x + 1
  z <- x * 2 # if you don't use return these two won't leave test1

  return(list(y=y, z=z)) # equivalent without return() is list(y=y, z=z)
#or: list(y=y, z=z)
}

test2 <- function(...){
  ret1 <- test1(x)
  print(ret1$y * ret1$z)
 #or: return(ret1$y * ret1$z)
}

Note that the use of return() is not necessary, since the last object not assigned in a function is returned automatically.

The use of return() may help with readability though.

A read about return().

RLave
  • 7,816
  • 3
  • 20
  • 35
0

Your problem is about variable assignation: you are using a 'simple' assignment with the <- symbol. This mean the variable is assigned within its block, for instance y is defined within test1(). This mean you can not reuse it outside because it is not defined outside of test1(). To perfoerm this, try the <<- assignment symbol which assigns a variable in the upper environment and thus allow it to be reused outside of the block in which it is defined.