我发现动物园的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
? (我知道我可以在没有变换的情况下工作,但对于简洁,简洁的代码来说,它是一个很好的工具。)
答案 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
。