下面是我的真实数据集的一个简单数据框架:
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),从所有阶段(phase1到phase3)中减去阶段3,这将使阶段1中的mm(1-3)为all -2,阶段2中为all -1,阶段3中为all 0。
R抛出一个错误"Error in Ops.data.frame(x,x3,):- only defined for equally sized frames“,就像我尝试的那样:
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
发布于 2014-03-07 02:03:34
好吧,我花了一点时间才弄明白你想要什么,但这里有一个解决方案:
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
一般来说,调试这类问题的最好方法是在传递给ddply
的函数中放入一条browser()
语句,这样您就可以在空闲时检查对象。这样做会揭示出:
传递给你的函数的数据帧包括ID列和cols.to.sub
)
mm
,然后利用向量回收从矩阵的其余部分减去一行。因为向量回收是column-wise.,所以我需要转置( t
)
https://stackoverflow.com/questions/22239745
复制