r - 再次 : Setting the environment within a function

标签 r function plyr environment

已经有很多关于范围、环境和功能的讨论。见例如herehere .但是,我不确定我是否找到了解决以下问题的好方法:

 df <- data.frame(id=rep(LETTERS[1:2],each=2), x=1:4)
 d <- -1
 myfun <- function(df, d){
          require(plyr)
          new.dat <- ddply(df, .(id), transform, x=x*d) 
          return(new.dat)}
 myfun(df, 1)

您可以轻松验证全局定义的 d=-1被使用,而不是 d=1如论据中所规定。 (如果不存在全局定义的 d,则返回 object not found 消息)现在最大的问题是:如何制作 d使用的函数的参数而不是全局定义的 d ?

我的印象是以下应该有效:
      myfun2 <- function(df, d){
          here <- environment()
          new.dat <- ddply(df, .(id), transform, x=x*with(here,d)) 
          return(new.dat)}
      myfun2(df, 1)

据我了解 with(here, d)检索对象 d来自环境 here .所以,结果应该是 1 .但是,返回错误,说
  Error in eval(substitute(expr), data, enclos = parent.frame()) : 
   invalid 'envir' argument of type 'closure' 

我不确定我是否理解为什么这不起作用,如果有人可以对此有所了解,或者您是否可以提供替代解决方案,我会很高兴。请注意,包装整个 ddply -声明成with(...)似乎也没有帮助。

一个有效的解决方案是 attach函数内部的当前环境:
 myfun3 <- function(df, d){
   here <- environment()
   attach(here)
   new.dat <- ddply(df, .(id), transform, x=x*d) 
   detach(here)
   return(new.dat)
 }

但我不喜欢这个解决方案,因为它通过屏蔽全局定义的 d 起作用。与本地d ,我认为这不是很优雅。

任何意见/指针表示赞赏。

最佳答案

唤醒惰性求值并确保您使用的是本地 d参数,使用 force .添加这一行:

d <- force(d)

开始myfun .

好吧,看来我误解了这个问题。在这种情况下,问题在于 ddply评价不标准,只看里面df应用转换时的变量,所以它看不到本地 d即使你force它。正如哈德利指出的,你需要包装 transform insdie 调用 here .
myfun <- function(df, d){
      require(plyr)
      new.dat <- ddply(df, .(id), here(transform), x=x*d) 
      return(new.dat)}

无关的小代码改进:
由于您对 require 的情况没有做任何事情返回 FALSE ,你应该把它换成 library .mutatetransform 替代品的改进型替代品.
您不需要显式 return .
myfun <- function(df, d){
      library(plyr)
      ddply(df, .(id), here(mutate), x=x*d)}

关于r - 再次 : Setting the environment within a function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587341/

相关文章:

function - Octave 函数未定义

r - 用户编写的函数将 NA 替换为 0,因为 for 循环在 r 中不起作用

在R中重复vector的元素

r - ggplot2 & stat_ellipse : Draw ellipses around multiple groups of points

r - 如何修复 ggplot2 中图例的这种奇怪行为?

regex - strsplit 与 gregexpr 不一致

r - 根据列总和对数据框进行子集化

javascript - 是否可以使用值数组作为参数来调用 JavaScript 函数?

r - 使用 as.factor 而不是 plyr 和 ddply 对 R 中的变量进行分组?

r - freq() 在打印期间重命名列