我们假设我有这个示例数据框:
df = data.frame(id=rep(1:2,each=5),v1=c(1:10),v2=c(1:10))
而且,比方说,我想创建一个新的列sumv1v2,它包含v1和v2的总和,仅当id = 1时(否则sumv1v2将为0)。
以下定义了预先定义的自定义函数,可以使用:
condisum = function(pid,pv1,pv2){
if (pid[1]==1) {pv1+pv2}
else {0}
}
df = ddply(df,"id",mutate,sumv1v2=condisum(id,v1,v2))
返回的数据帧是我需要的:
df
id v1 v2 sumv1v2
1 1 1 1 2
2 1 2 2 4
3 1 3 3 6
4 1 4 4 8
5 1 5 5 10
6 2 6 6 0
7 2 7 7 0
8 2 8 8 0
9 2 9 9 0
10 2 10 10 0
但是我可以在ddply()
内定义内联函数,就像匿名函数一样吗?我试过这个:
df = data.frame(id=rep(1:2,each=5),v1=c(1:10),v2=c(1:10))
df = ddply(df,"id",mutate,sumv1v2=function(pid,pv1,pv2){
if (pid[1]==1) {pv1+pv2}
else {0}
}(id,v1,v2))
我收到此错误消息:
Error: attempt to replicate an object of type 'closure'
我知道我无法将函数传递给mutate
,并且应该传递一个表达式,这要归功于Gregor在这篇文章中的出色评论:
Use of ddply + mutate with a custom function?
所以我试图传递一个带有参数的匿名函数。这会成为一种表达吗?但我仍然有错误。
那么,是否可以不事先定义自定义函数,并在function()
内使用ddply()
定义它?
答案 0 :(得分:1)
经过更多的试验,我终于意识到了这个问题。
现在可以使用以下内容:
df = data.frame(id=rep(1:2,each=5),v1=c(1:10),v2=c(1:10))
df = ddply(df,"id",mutate,sumv1v2=(function(pid,pv1,pv2){
if (pid[1]==1) {pv1+pv2}
else {0}
})(id,v1,v2))
记下匿名函数周围的新(
和)
。猜猜这最后把它变成了一个函数,并且用(id,v1,v2)
来传递参数,整个事情最终变成了一个表达式。
以简单的形式,我试过这个:
x = function(y){y^2}(3)
x
和x返回:
function(y){y^2}(3)
但是,如果我添加(
和)
:
x = (function(y) y^2)(3)
x
x返回:
[1] 9
答案 1 :(得分:1)
或者你可以在ddply
调用的范围内定义函数,然后使用它。这可能使整个事情更容易阅读。
df <- data.frame(id=rep(1:2,each=5),v1=c(1:10),v2=c(1:10))
df <- ddply(
df,
"id",
mutate,
sumv1v2={
f <- function(pid,pv1,pv2) {
if (pid[1]==1) pv1 + pv2
else 0
}
f(id,v1,v2)
}
)