6

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

我对使用函数()以及何时使用函数(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()。

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

4

1 回答 1

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根据 column 中的值分成几个较小的数据框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 和名称来创建一些令人困惑的东西。

于 2013-08-29T21:10:49.750 回答