【问题标题】:Tabulating groups by row and column in R, WITHOUT looping在R中按行和列对组进行制表,没有循环
【发布时间】:2016-08-07 05:26:06
【问题描述】:

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

不循环(因为矩阵的维度会很大,循环太慢)

给定这个矩阵,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 

【问题讨论】:

  • 抱歉,我的其他处理器中第一列是粗体的,现在清楚了吗?
  • 否决票是怎么回事?

标签: r matrix group-by dplyr


【解决方案1】:

通过删除最后一列和最后一行来创建“A1”,将“A”矩阵子集,将行名和列名与最后一列/行,melt 更改为“长”格式,转换为 @987654322 @, dcast 将其设置为“宽”(在获取行数后或仅在dcast 中将fun.aggregate 用作length

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)

或者我们可以在使用rep 转换为“长”格式后使用base R 中的table

table(data.frame(RowCol = paste(rep(colnames(A1), nrow(A1)), 
             rep(rownames(A1), ncol(A1)), sep = "_"), c(A1)))

【讨论】:

  • 请问........如果在原始表格中我们从未观察到“3”,但我们仍希望在表格中考虑它?
  • @robertevansanders 您可以将c(A1) 转换为factor,将levels 指定为1:3,然后执行table
  • 这样的? A1 = as.factor(A1,levels=c('1','2','3'))? c(A1)是什么意思
  • @robertevansanders 我认为应该是factor(c(A), levels = 1:3)
  • @robertevansanders 我的意思是在melting 之后将value 列更改为factor,即dcast(setDT(melt(A1))[, value := factor(value, levels = 1:3)], Var1+ Var2 ~value, length, drop = FALSE)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 2015-04-12
  • 2021-12-03
相关资源
最近更新 更多