在R中按行和列制表组,没有循环

时间:2016-08-07 05:26:06

标签: r matrix group-by dplyr

如果标题更清晰,请随时编辑标题。这是我想要做的。

没有循环(因为矩阵的尺寸非常大,循环太慢。)

鉴于此矩阵,A

  A = rbind(
    c(2, 2, 1, 1, 2, 2, 2  ),
    c(2, 2, 3, 2, 2, 3, 2  ),
    c(1, 1, 1, 2, 2, 1, 1  ),
    c(1, 1, 1, 1, 1, 1, 1  ),
    c(1, 2, 1, 1, 1, 1, 1  ),
    c(2, 2, 1, 1, 1, 1, 2  ),
    'S'=c(1, 2, 3, 4, 5, 6, 7))

A = cbind(A,'R'=c(rep(1:2,3),NA))  

                 R
  2 2 1 1 2 2 2  1
  2 2 3 2 2 3 2  2
  1 1 1 2 2 1 1  1
  1 1 1 1 1 1 1  2
  1 2 1 1 1 1 1  1
  2 2 1 1 1 1 2  2
S 1 2 3 4 5 6 7 NA

我们将底行称为“S”,最后一列称为“R”

我想按R和S进行分组,基本上返回每个组的TABLE()函数,例如,

S=1, R =1

         R
  **2**  1

  **1**  1

  **1**  1

S   1    

棘手的部分是当并非所有值都显示出来时,我仍然需要将其列为第三列的0。 (所以也许我需要一些解决方法)...... 基本上,该表将返回:

1 2 3
2 1 0 

I would like the resulting thing to be 

(R * S) x 3 


And the output would be:

2 1 0
1 2 0 
3 0 0 
2 1 0 
1 2 0 
2 1 0 
2 1 0 
1 2 0 
1 2 0 
2 0 1
2 1 0 
2 1 0 
2 0 1
1 2 0 

1 个答案:

答案 0 :(得分:2)

通过删除最后一列和最后一行来设置'A'矩阵以创建'A1',使用最后一列/行更改rownames和列名称,melt更改为'long'格式,转换为data.tabledcast将其设置为“广泛”(获取行数或在fun.aggregate中仅使用length作为dcast

library(reshape2)
library(data.table)
A1 <- A[-nrow(A), -ncol(A)]
row.names(A1) <- A[-nrow(A),"R"]
colnames(A1) <- A["S", - ncol(A)]
dcast(setDT(melt(A1))[,.N ,.(RowCol = paste(Var2, Var1, sep="_"), value)], 
              RowCol~value,value.var="N", fill = 0)
#    RowCol 1 2 3
# 1:    1_1 2 1 0
# 2:    1_2 1 2 0
# 3:    2_1 1 2 0
# 4:    2_2 1 2 0
# 5:    3_1 3 0 0
# 6:    3_2 2 0 1
# 7:    4_1 2 1 0
# 8:    4_2 2 1 0
# 9:    5_1 1 2 0
#10:    5_2 2 1 0
#11:    6_1 2 1 0
#12:    6_2 2 0 1
#13:    7_1 2 1 0
#14:    7_2 1 2 0

或者,如果我们不需要paste行/列名称

dcast(setDT(melt(t(A1))), Var1+Var2~value, length)

或者我们可以在使用table

转换为“长”格式后使用base R中的rep
table(data.frame(RowCol = paste(rep(colnames(A1), nrow(A1)), 
             rep(rownames(A1), ncol(A1)), sep = "_"), c(A1)))