在函数内部使用时,transform.zoo无法访问变量

时间:2013-06-27 15:44:43

标签: r function zoo

我发现动物园的transform在函数体中使用时无法使用额外的(即不是动物园对象的一部分)变量

让我解释一下:

我在提示符处输入以下代码,以创建一个小的两列动物园对象z,并添加一个从现有列和变量x计算的新列:

library(zoo)
z <- zoo(matrix(1:10, ncol=2, dimnames=list(NULL, c("a", "b"))), order.by=2001:2005)
x <- 2
transform(z, c = x*a)

我得到了所需的结果,一个带有新列c的动物园对象。这里没问题。

现在我想在函数体中使用transform;计算变量作为参数传递给函数:

rm(x)
f <- function(data, x) { transform(data, c = x*a) }
f(z, 2)

这会以Error in eval(expr, envir, enclos) (from #1) : object 'x' not found停止。如果我在提示时指定x <- 2,则可以正常工作(因此上面的rm(x)。)

使用数据框(即transform.data.frame)没有问题。

我认为当transform.zoo调用transform.data.frame时,f的形式的绑定就会丢失。我不太了解R的环境,无法找出这里到底出了什么问题。

编辑添加:transform不仅不能获得形式,而且函数体内也没有变量。

有没有办法让transform看到x? (我知道我可以在没有变换的情况下工作,但对于简洁,简洁的代码来说,它是一个很好的工具。)

1 个答案:

答案 0 :(得分:2)

我认为最好的建议是:不要那样做!

transform()with()subset()非常适合在顶级使用,以便更轻松地编写数据操作代码。如果您正在编写函数,则应使用常规替换函数[<-[[<-,具体取决于您正在执行的操作。

如果您不相信我,请参阅?transform

中的警告
Warning:

    This is a convenience function intended for use interactively.
    For programming it is better to use the standard subsetting
    arithmetic functions, and in particular the non-standard
    evaluation of argument ‘transform’ can have unanticipated
    consequences.

使用[<-[或其他功能的意思是写f这样

f <- function(obj, x) {
  cd <- coredata(obj)
  cd <- cbind(cd, c = x * cd[, "a"])
  zoo(cd, index(obj), attr(obj, "frequency"))
}

f(z, 2)

这给出了期望的结果

> transform(z, c = x*a)
     a  b  c
2001 1  6  2
2002 2  7  4
2003 3  8  6
2004 4  9  8
2005 5 10 10
> f(z, 2)
     a  b  c
2001 1  6  2
2002 2  7  4
2003 3  8  6
2004 4  9  8
2005 5 10 10

f很复杂,因为coredata(obj)是一个矩阵。

可能更整洁
f2 <- function(obj, x) {
    cd <- as.data.frame(coredata(obj))
    cd[, "c"] <- x * cd[, "a"] ## or cd$c <- x * cd$a
    zoo(cd, index(obj), attr(obj, "frequency"))
}

f2(z, 2)

> f2(z, 2)
     a  b  c
2001 1  6  2
2002 2  7  4
2003 3  8  6
2004 4  9  8
2005 5 10 10

您真的需要了解要使用transform()的环境和评估框架 - 您不能学会使用eval(),这是transform()内部调用的内容,并为envir(要评估的环境)和enclos机箱指定正确的值。请参阅?eval