我有点困惑。我经常使用像这样的变换
ddply(data.frame, 1, transform, new.column = function(old.col.1,old.col.2,...))
但最近I asked a question和哈德利说过:
不要使用变换。它是一个适合交互使用的辅助函数,而不是用于编程。
转换错了吗?我想我现在确信这是愚蠢的:
transform(data.frame,col2=fun(col1)).
但它在ddply设置中不是很有用吗?
答案 0 :(得分:1)
在transform
中使用ddply
和将函数transform()
作为独立使用之间存在差异。这样做会好得多(也更快):
Mydata$col3 <- fun(Mydata$col1, Mydata$col2)
如果要更改多个列,函数组合ddply / transform特别有用,例如
Mynewdata <- ddply(Mydata,1,transform,col3=fun1(col1,col2), col4=fun2(col1,col2))
即便如此,您还可以使用within()
更灵活的选项,允许您使用计算结果来计算下一行:
Mynewdata <- within(Mydata,{
col2 <- fun1(col1)
col3 <- fun2(col1,col2)
})
transform()
的东西是它特别编写为交互使用。如果在函数中使用它,可能会遇到麻烦。它以这种方式类似于subset()
:它们是便利功能,但它们在更复杂的代码中使用既不快也不安全。
ddply()
的意见不同。在某些情况下,它可以快速工作,并提供非常干净和可读的代码,在其他情况下,我认为它严重矫枉过正。当您必须使用非向量化函数时,ddply()
通常可以更快更轻松地工作,在这种情况下,上述选项将无效。但为此,您还可以选择使用mapply:
Mynewdata <- within(Mydata, col3 <- mapply(myfun,col1,col2))
在这种情况下,mapply也可以更快。给你一个基本的例子:
Mydata <- data.frame(col1=rnorm(5),col2=rpois(5,3))
myfun <- function(x,y){
if(y == 0) mean(x) else
mean(c(x,seq(1,y,by=1)))
}
code1 <- expression(Newdata <- ddply(Mydata,1,transform,col3=myfun(col1,col2)))
code2 <- expression(Newdata2 <- within(Mydata, col3 <- mapply(myfun,col1,col2)))
> benchmark(code1,code2)
test replications elapsed relative
1 code1 100 0.50 12.5
2 code2 100 0.04 1.0
我对ddply()
的主要问题是,无法保证观察的顺序,如下面的示例输出中所示:
Mydata Newdata2 Newdata
col1 col2 col1 col2 col3 col1 col2 col3
1 0.07060223 4 | 0.07060223 4 2.0141204 | 0.05658259 2 1.0188609
2 1.84645791 2 | 1.84645791 2 1.6154860 | 0.07060223 4 2.0141204
3 0.05658259 2 | 0.05658259 2 1.0188609 | 0.84119845 1 0.9205992
4 0.89998084 5 | 0.89998084 5 2.6499968 | 0.89998084 5 2.6499968
5 0.84119845 1 | 0.84119845 1 0.9205992 | 1.84645791 2 1.6154860
这两个函数都计算出正确的结果,但是mapply()
在这种情况下更快 并且保留了数据框中观察的顺序。