Push the assignment of results
one more level above to your global environment should solve your problem.
myfunction <- function( X ) {
plot(X, type="l")
max_B <- max(X$B)
max_A <- X$A[ X$B == max_B ]
results <<- c(max_A, max_B)
points(max_A, max_B, col="red")
}
myfunction(dat)
For more information of <<-
, check How do you use “<<-” (scoping assignment) in R?, and also the Environment chapter in Advanced R written by Hadley Wickham. You'll learn more about how R scopes variables across environments.
Why isn't the normal return working?
We may return
local variables out to Global Environment, but remember that returns only the values of returned local variables, but not the local variables themselves.
For example, if we create a function simply adds one to a given number:
add1 <- function(x) {
y <- x + 1
return(y)
# return(x + 1) will also do but I save it as y for better demonstration
}
add1(1)
gives us 2 on the screen, but doesn't give us a variable called "y" in Global Environment. If we really want an y
out there, we have to save the results from add(1)
and name it as "y", i.e. y <- add1(1)
. Instead of showing "2" on the screen, now it is saved as y
.
The trick of <<-
is pushing the assignment to its parent environment. In this answer, results <<- c(max_A, max_B)
takes place in myfunction
, whose parent environment happens to be Global Environment, so we'll find results
after executing myfunction
.
Why can I use the objects for to plot the point, but not to save the very same objects into a new object?
The objects max_A
and max_B
are effective locally in myfunction
, so you can do whatever you want within that scope. In your original codes, results
was indeed saved but still existed only in myfunction
environment.
One thing worth mentioning is that, unlike most other functions, plot
and points
returns no object but graphics, so they are not limited by the environment scopes. You can try x <- 1:10; y <- x + rnorm(10); myplot <- plot(x, y)
, and you'll see a plot but myplot
is empty.