如何模拟引用传递的参数

时间:2018-04-02 10:01:18

标签: r reference parameter-passing

有办法吗?
NB :问题不在于做这样的事情是对的,好的还是明智的。
问题是,如果有办法,所以如果你的答案是 “你为什么想这么做?” “R使用你想要的函数曾经被称为程序和良好的R用法/风格不......”,“你能解释得更好吗......提供一些代码”不要回答。

我做了一个快速的尝试,无法正常工作最终使用环境,或多或少:

function(mydf) {
  varName <- deparse(substitute(mydf))
  ...
  assign(varName,mydf,envir=parent.frame(n = 1))
}  

3 个答案:

答案 0 :(得分:1)

至少对于我的特定/有限需求,我找到了解决方案

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

答案 1 :(得分:1)

1)将函数体包裹在eval.parent(substitute({...}))中,如下所示:

f <- function(x) eval.parent(substitute({
  x <- x + 1
}))

mydf <- data.frame(z = 1)
f(mydf)
mydf
##   z
## 1 2

另请参阅gtools中的defmacro函数和wrapr包。

2)替代方法可能是使用替换函数:

"incr<-" <- function(x, value) {
      x + value
}

mydf <- data.frame(z = 1)
incr(mydf) <- 1
mydf
##   z
## 1 2

3)或只是覆盖输入:

f2 <- function(x) x + 1
mydf <- data.frame(z = 1)
mydf <- f2(mydf)
mydf
##   z
## 1 2

如果问题是有多个输出,那么在gsubfn包中使用list。这在带有方括号的赋值的左侧使用,如图所示。见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 :(得分:0)

我认为没有办法模仿按引用调用。但是,可以根据具体情况使用一些技巧:

globals:当然,可以使用全局变量而不是参数。这可以使用&lt;&lt; - 而不是=或&lt; - 来在函数中编写。通过这种方式,许多需要逐个调用的情况消失了。

但是,这与并行化不兼容,也与递归不兼容。

当你需要递归时,你可以做很多相同的事情并拥有一个全局堆栈。在递归调用之前,您必须附加到此堆栈,并且作为函数的第一行,您可以获取索引(类似于CPU中的堆栈指针)以便写入全局堆栈。

这两种方法都不受鼓励,应该作为最后的手段或用于教育。如果你真的无法避免调用引用,请转到C ++ with Rcpp并编写一个C ++函数来完成繁重的工作。如果需要,它实际上可以调用R函数。看看一些Rcpp教程,其中大部分都涵盖了这个案例......