基于 R 中的查找表聚合矩阵

Posted

技术标签:

【中文标题】基于 R 中的查找表聚合矩阵【英文标题】:Aggregate a matrix based on a lookup table in R 【发布时间】:2020-09-04 19:50:06 【问题描述】:

我尝试使用存储在 R 中另一个查找表 (.csv) 中的信息来聚合一个大矩阵 (.csv)。

An example of the large matrix:
   z1 z2 z3 z4 z5 z6 z7 z8
z1  1  1  1  1  1  1  1  1
z2  2  2  2  2  2  2  2  2
z3  3  3  3  3  3  3  3  3
z4  0  0  0  0  0  0  0  0
z5  1  1  1  1  1  1  1  1
z6  2  2  2  2  2  2  2  2
z7  1  1  1  1  1  1  1  1
z8  0  0  0  0  0  0  0  0

我有一个查找表告诉我哪些区域要聚合在一起,例如:

old  new
z1   D1
z2   D1
z3   D1
z4   D4
z5   D4
z6   D6
z7   D7
z8   D7

这意味着我需要将 z1、z2、z3 聚合到一个组中。 z4 和 z5 进入另一个组,依此类推...

基于这个查找表,我将创建一个如下所示的新矩阵:

    D1  D4  D6  D7
D1  18  12   6  12
D4   3   2   1   2
D6   6   4   2   4
D7   3   2   1   2

这是通过根据查找表将原始矩阵中的元素按如下所示的块求和来完成的:

     z1 z2 z3   z4 z5   z6   z7 z8

z1   1  1  1    1  1    1    1  1
z2   2  2  2    2  2    2    2  2
z3   3  3  3    3  3    3    3  3

z4   0  0  0    0  0    0    0  0
z5   1  1  1    1  1    1    1  1

z6   2  2  2    2  2    2    2  2

z7   1  1  1    1  1    1    1  1
z8   0  0  0    0  0    0    0  0

我很想知道如何在 R 中有效地做到这一点。非常感谢。

【问题讨论】:

感谢 Martine Gal 的编辑。谢谢你的评论,阿克伦。为了解决这个问题,我能想到的一种方法是将查找列“新”添加到原始矩阵中,然后根据这个添加的列对行进行分组。然后,然后以类似的方式对列进行分组。但想知道是否有更聪明的方法。 【参考方案1】:

我们可以通过outer 做到这一点

un1 <- unique(df1$new)    
out <- outer(un1, un1, FUN = Vectorize(function(x, y)  
         sum(m1[df1$old[df1$new == x], df1$old[df1$new == y]])))
dimnames(out) <- list(un1, un1)
out
#   D1 D4 D6 D7
#D1 18 12  6 12
#D4  3  2  1  2
#D6  6  4  2  4
#D7  3  2  1  2

数据

df1 <- structure(list(old = c("z1", "z2", "z3", "z4", "z5", "z6", "z7", 
"z8"), new = c("D1", "D1", "D1", "D4", "D4", "D6", "D7", "D7"
)), class = "data.frame", row.names = c(NA, -8L))

m1 <- structure(c(1L, 2L, 3L, 0L, 1L, 2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 
2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 
2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 
2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 1L, 0L, 1L, 2L, 3L, 0L, 1L, 
2L, 1L, 0L), .Dim = c(8L, 8L), .Dimnames = list(c("z1", "z2", 
"z3", "z4", "z5", "z6", "z7", "z8"), c("z1", "z2", "z3", "z4", 
"z5", "z6", "z7", "z8")))

【讨论】:

这太棒了!感谢您的快速解决方案。真的很感激。 我的 R 技能不够先进,无法完全理解代码,但我能够将您的解决方案应用于我的数据。我发现结果有一些问题。如果查找表是这样的,代码会起作用吗?旧:z1、z2、z3、z4、z5、z6、z7、z8,新:D1、D2、D1、D4、D5、D1、D2、D4。那就是新ID对应不连续的旧ID组? @njwork 它。应该。有。工作。因为。我们。是。循环上。唯一值,然后执行==。在这里,我假设了列。是character 类。旧的,新的 非常感谢您的解决方案。但是,经过几轮检查,结果似乎仍然不对。似乎每当New ID对应一组连续的Old ID时,结果都是正确的。如果New ID对应几个不连续的Old ID组,则结果不正确。在我的示例中,旧 ID 和新 ID 是字符,但在我的真实数据中,它们是数字(不确定这是否重要)。 对不起!我在检查时犯了一个错误。您的代码完美运行,结果绝对正确。再次,真的很抱歉我的错误。非常感谢您的帮助。

以上是关于基于 R 中的查找表聚合矩阵的主要内容,如果未能解决你的问题,请参考以下文章

基于与 Hive 中的数组比较的聚合列

Numpy中的矩阵运算+聚合操作+arg运算(2019.1.17)

查询以查找要聚合的不同字符串

查找 SQL 聚合函数调用中的百分比可能没有嵌套聚合或窗口函数

使用 r,我如何将不是基本聚合函数的函数 (moments::skewness) 应用于分组表?

为啥聚合+排序比mongo中的查找+排序更快?