这与我在How to summarize by group?看到的这个问题有关,但是,似乎我的数据有点不同,这使得事情变得奇怪。 我有一个data.frame DF,如下所示:
X Y1 Y2 Y3 Y4
3 A A B A
2 B B A A
1 B A A A
我想通过X中的数值对Y中的每个唯一因子进行加权求和,使得输出为:
Y Y1 Y2 Y3 Y4
A 3 4 3 6
B 3 2 3 0
我曾尝试使用for循环来迭代列的索引,但是我无法正确传递Y的数量,并且它似乎不是R方式有效地执行此操作,更多的列和行。
看起来根据链接的问题,这是正确的方法,但是,当我尝试扩展以在所有列中执行相同操作时,通过group_by和summarise_each,我得到错误,因为Y是因素。我应该使用“申请”吗?这个逻辑似乎是直截了当的,但我一直被其实施所困扰。
aggregate(X~Y1,DF,sum)
答案 0 :(得分:4)
我认为这不是直截了当的,需要融化和重塑。这是data.table
的尝试:
setDT(df)
dcast(melt(df, id.vars="X", value.name="Y")[,.(X=sum(X)), by=.(variable,Y)], Y ~ variable)
#Using 'X' as value column. Use 'value.var' to override
# Y Y1 Y2 Y3 Y4
#1: A 3 4 3 6
#2: B 3 2 3 NA
如果您想避开大部分xtabs
代码,甚至可以使用data.table
:
xtabs(X ~ Y + variable, melt(df, id.vars="X", value.name="Y"))
或仅使用基础R的变体:
xtabs(X ~ ., cbind(df[1], stack(lapply(df[-1],as.character))) )
答案 1 :(得分:0)
我无法使用data.table
包来完成上述工作,因此我只是编写了自己的函数来执行此操作。
#@param x = vector of strings that we want to identify
#@param DF = data frame, with the first column as weights and the rest containing strings
#@return a matrix with the same cols and rows as identifiers. contains the summed weights
return_reshape = function(x , DF) {
store_mat = matrix(0.0,length(x),ncol(DF) - 1)
dimnames(store_mat) = list(x,colnames(DF)[-1])
for (row in 1:nrow(DF)) {
for (index in 1:length(x)) {
col_index = DF[row,-1] == x[index ]
store_mat[index ,col_index] = store_mat[index ,col_index] + as.numeric(DF[row,1])
}
}
store_mat
}
DF = data.frame(X=3:1, Y1 = c("A","B","B"),Y2 = c("A","B","A"),Y3 = c("B","A","A"),Y4 = c("A","A","A"),stringsAsFactors=FALSE)
x = as.character(c("A", "B"))
return_reshape(x,DF)
Y1 Y2 Y3 Y4
A 3 4 3 6
B 3 2 3 0
答案 2 :(得分:0)
这实际上是一个矩阵%*%
另一个矩阵。
X = matrix(c(3,2,1), nrow = 1)
X
[,1] [,2] [,3]
[1,] 3 2 1
Y_A = matrix(c(1,1,0,1,0,0,1,1,0,1,1,1), nrow = 3, byrow = T)
Y_A
[,1] [,2] [,3] [,4]
[1,] 1 1 0 1
[2,] 0 0 1 1
[3,] 0 1 1 1
Y_B = 1- Y_A
Y_B
[,1] [,2] [,3] [,4]
[1,] 0 0 1 0
[2,] 1 1 0 0
[3,] 1 0 0 0
X %*% Y_A
[,1] [,2] [,3] [,4]
[1,] 3 4 3 6
X %*% Y_B
[,1] [,2] [,3] [,4]
[1,] 3 2 3 0