我正在尝试使用plyr包中的ddply将函数应用于数据帧,但是我得到了一些我不理解的结果。我有3个问题 结果
假设:
mydf<- data.frame(c(12,34,9,3,22,55),c(1,2,1,1,2,2)
, c(0,1,2,1,1,2))
colnames(mydf)[1] <- 'n'
colnames(mydf)[2] <- 'x'
colnames(mydf)[3] <- 'x1'
mydf看起来像这样:
n x x1
1 12 1 0
2 34 2 1
3 9 1 2
4 3 1 1
5 22 2 1
6 55 2 2
如果我这样做:
k <- function(x) {
mydf$z <- ifelse(x == 1, 0, mydf$n)
return (mydf)
}
mydf <- ddply(mydf, c("x") , .fun = k, .inform = TRUE)
我收到以下错误:
Error in `$<-.data.frame`(`*tmp*`, "z", value = structure(c(12, 34, 9, :
replacement has 3 rows, data has 6
Error: with piece 1:
n x x1
1 12 1 0
2 9 1 2
3 3 1 1
无论是否将要拆分的变量指定为c(“x”),“x”或。(x),我都会收到此错误。我不明白为什么我收到此错误消息。
但是,我真正想做的是设置一个if / else函数,因为我的数据集有变量x1,x2,x3和x4,我也想考虑这些变量。但是当我尝试一些简单的事情时,例如:
j <- function(x) {
if(x == 1){
mydf$z <- 0
} else {
mydf$z <- mydf$n
}
return(mydf)
}
mydf <- ddply(mydf, x, .fun = j, .inform = TRUE)
我明白了:
Warning messages:
1: In if (x == 1) { :
the condition has length > 1 and only the first element will be used
2: In if (x == 1) { :
the condition has length > 1 and only the first element will be used
我很困惑使用function()以及何时使用function(x)。对j()或k()使用function()会给出一个不同的错误:
Error in .fun(piece, ...) : unused argument (piece)
Error: with piece 1:
n x x1 z
1 12 1 0 12
2 9 1 2 9
3 3 1 1 3
4 12 1 0 12
5 9 1 2 9
6 3 1 1 3
7 12 1 0 12
8 9 1 2 9
9 3 1 1 3
10 12 1 0 12
11 9 1 2 9
12 3 1 1 3
其中列z不正确。然而,我看到很多函数都写成function()。
我真诚地感谢任何可以帮助我解决此问题的评论
答案 0 :(得分:11)
这里需要解释很多。让我们从最简单的情况开始。在您的第一个示例中,您只需要:
mydf$z <- with(mydf,ifelse(x == 1,0,n))
等效的ddply
解决方案可能如下所示:
ddply(mydf,.(x),transform,z = ifelse(x == 1,0,n))
可能你最大的困惑之处在于你似乎不明白作为ddply
中的函数的参数传递的是什么。
考虑你的第一次尝试:
k <- function(x) {
mydf$z <- ifelse(x == 1, 0, mydf$n)
return (mydf)
}
ddply
的工作方式是根据mydf
列中的值将x
分成几个较小的数据框。这意味着,每次ddply
调用k
时,传递给k
的参数都是数据框。具体来说,是您主要数据框的一个子集。
因此,在k
中,x
是mydf
的子集,包含所有列。您不应该尝试从mydf
内修改k
。修改x
,然后返回修改后的版本。 (如果必须,但我上面显示的选项更好。)所以我们可能会像这样重写你的k
:
k <- function(x) {
x$z <- ifelse(x$x == 1, 0, x$n)
return (x)
}
请注意,您使用x
作为k
和的参数作为我们其中一列的名称,从而创建了一些令人困惑的内容。