R ddply,应用if和ifelse函数

时间:2013-08-29 20:47:11

标签: r plyr

我正在尝试使用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

问题#1

如果我这样做:

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),我都会收到此错误。我不明白为什么我收到此错误消息。

问题#2

但是,我真正想做的是设置一个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

问题#3

我很困惑使用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()。

我真诚地感谢任何可以帮助我解决此问题的评论

1 个答案:

答案 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中,xmydf的子集,包含所有列。您不应该尝试从mydf内修改k。修改x,然后返回修改后的版本。 (如果必须,但我上面显示的选项更好。)所以我们可能会像这样重写你的k

k <- function(x) {
  x$z <- ifelse(x$x == 1, 0, x$n)
  return (x)
}

请注意,您使用x作为k 的参数作为我们其中一列的名称,从而创建了一些令人困惑的内容。