2016-10-20 56 views
1

這與我看過的How to summarize by group?這個問題有關,但是,似乎我的數據有點不同,這讓事情變得很奇怪。 我有data.frame DF像這樣:R:通過多列數求和

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) 

回答

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)))) 
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 
+0

我沒有看到@thelatemail了'xtabs'的解決方案,是很好的 –

+0

試着做'df'一個'data.table'對象首先通過'setDT(DF)' - 我剛剛測試了代碼再次,它工作正常。 – thelatemail

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