R ddply有多个变量

时间:2014-03-07 01:32:52

标签: r plyr

这是我的真实数据集的简单数据框:

df <- data.frame(ID=rep(101:102,each=9),phase=rep(1:3,6),variable=rep(LETTERS[1:3],each=3,times=2),mm1=c(1:18),mm2=c(19:36),mm3=c(37:54))

我想首先按ID和变量分组,然后对于值(mm1,mm2,mm3),从所有阶段(阶段1到阶段3)中减去阶段3,这将使阶段1中的mm(1-3)全部-2,阶段2全-1,阶段3全0。

R抛出错误“Ops.data.frame(x,x [3,])中的错误: - 仅为同等大小的数据帧定义” 我试过了:

df1 <- ddply(df, .(ID, variable), function(x) (x - x[3,]))   

任何建议都将不胜感激。 输出应如下所示:

ID phase variable mm1 mm2 mm3
101  1      A     -2  -2  -2
101  2      A     -1  -1  -1
101  3      A      0   0   0
101  1      B     -2  -2  -2
101  2      B     -1  -1  -1
101  3      B      0   0   0
101  1      C     -2  -2  -2
101  2      C     -1  -1  -1
101  3      C      0   0   0
102  1      A     -2  -2  -2
102  2      A     -1  -1  -1
102  3      A      0   0   0
102  1      B     -2  -2  -2
102  2      B     -1  -1  -1
102  3      B      0   0   0
102  1      C     -2  -2  -2
102  2      C     -1  -1  -1
102  3      C      0   0   0

1 个答案:

答案 0 :(得分:3)

好的,带我一点弄清楚你想要什么,但这是一个解决方案:

cols.to.sub <- paste0("mm", 1:3)
df1 <- ddply(
  df, .(ID, variable), 
  function(x) {
    x[cols.to.sub] <- t(t(as.matrix(x[cols.to.sub])) - unlist(x[x$phase == 3, cols.to.sub]))
    x
} ) 

这会产生(前6行):

    ID phase variable mm1 mm2 mm3
1  101     1        A  -2  -2  -2
2  101     2        A  -1  -1  -1
3  101     3        A   0   0   0
4  101     1        B  -2  -2  -2
5  101     2        B  -1  -1  -1
6  101     3        B   0   0   0

一般来说,调试此类问题的最佳方法是在传递给browser()的函数中放入ddply语句,这样您就可以随意查看对象。这样做会显示:

  1. 传递给您的函数的数据框包括ID列以及阶段列,因此您的mm列不是前三列(因此需要定义cols.to.sub
  2. 即使你解决了这个问题,你也无法对尺寸不等的数据帧进行操作,所以我在这里做的是转换为矩阵,然后利用向量回收从矩阵的其余部分中减去一行。我需要t(转置)因为向量回收是按列的。