问题
Is there a way?
NB: the question is not whether it is right, good or sensible to do such a thing.
The question is if there is a way, so if your answer would be
"why would you want to do that?" "R uses functions what you want was once called procedure and good R usage/style does not ...", "could you explain better... provide some code" do NOT answer.
I did a quick try, that did not work eventually worked, using environments, more or less:
function(mydf) {
varName <- deparse(substitute(mydf))
...
assign(varName,mydf,envir=parent.frame(n = 1))
}
回答1:
1) Wrap the function body in eval.parent(substitute({...}))
like this:
f <- function(x) eval.parent(substitute({
x <- x + 1
}))
mydf <- data.frame(z = 1)
f(mydf)
mydf
## z
## 1 2
Also see the defmacro
function in gtools and the wrapr package.
2) An alternative might be to use a replacement function:
"incr<-" <- function(x, value) {
x + value
}
mydf <- data.frame(z = 1)
incr(mydf) <- 1
mydf
## z
## 1 2
3) or just overwrite the input:
f2 <- function(x) x + 1
mydf <- data.frame(z = 1)
mydf <- f2(mydf)
mydf
## z
## 1 2
If the problem is that there are multiple outputs then use list
in the gsubfn package. This is used on the left hand side of an assignment with square brackets as shown. See help(list, gsubfn)
library(gsubfn)
f3 <- function(x, y) list(x + 1, y + 2)
mydf <- mydf2 <- data.frame(z = 1)
list[mydf, mydf2] <- f3(mydf, mydf2)
mydf
## z
## 1 2
mydf2
## z
## 1 3
回答2:
At least for my specific/limited needs I found a solution
myVar = 11
myF <- function(x) {
varName <- deparse(substitute(x))
# print(paste("var name is", varName))
x = 99
assign(varName,x,envir=parent.frame(n = 1))
NA # sorry this is not a function
# in real life sometimes you also need procedures
}
myF(myVar)
print(myVar)
# [1] 99
回答3:
I think there is no way to emulate call-by-reference. However, several tricks can be used from case to case:
globals: It is, of course, possible to have a global variable instead of the parameter. This can be written from within a function using <<- instead of = or <-. In this way, many cases of needing call-by-reference vanish.
However, this is not compatible with parallelization and also not compatible with recursion.
When you need recursion, you can do very much the same and have a global stack. Before the recursive call, you have to append to this stack and as the first line of your function, you can get the index (similar to a stack pointer in CPUs) in order to write to the global stack.
Both approaches are not encouraged and should be used as a last resort or for education. If you really can't avoid call-by-reference, go to C++ with Rcpp and write a C++-function that does your heavy loading. If needed, it can actually call R functions. Look at some Rcpp tutorials, most of them cover this case...
来源:https://stackoverflow.com/questions/49609171/how-to-emulate-parameters-passed-by-reference