R:通过多列的计数求和

时间:2016-10-20 04:06:50

标签: r

这与我在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)

3 个答案:

答案 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