如何根据条件汇总?

时间:2016-01-12 22:01:18

标签: r

我正在学习R.我会汇总看起来像这样的数据:

ID   Score  Elements
231  123    "a,b,c"
132  123    "b,c,d"
321  123    "e"
645  123    "d, f"
321  200    "foo,bar,baz"

我想组合一个元素匹配的所有行。由于共享的b / c和d,上面会产生3行,只有行1,2,3组合。可能有数百行必须组合或相同的行。

输出应为:

Score  Elements
123    "a,b,c,d,f"
123    "e"
200    "foo,bar,baz"

我目前在分数列上使用aggregate,因为这几乎是一个好的群组标识符,但在某些极端情况下,有一些群组具有相同的分数('e'in以上)。我正在使用自定义组合器函数将Score值组合成字符串向量。我目前的代码是:

customCombiner <- function(foo) {
    return(unique(unlist(strsplit(paste(as.vector(foo), collapse = ","),','))))
}
result = aggregate(
    myDataFrame$Elements,
    by=list(score=myDataFrame$score),
    customCombiner
)

是否可以聚合行,但首先检查它们是否应该聚合?或者是我的问题的另一种解决方案?

1 个答案:

答案 0 :(得分:1)

这实际上是一个棘手的问题;您将需要找到无向图的组件,其中数据的每一行都是一个节点,如果它们有任何元素重叠,则它们之间有边。

首先,您应该使用strsplit()清理数据,这将为您提供一系列集合,类似于:

m <- list(c('a','b','c'), c('b','c','d'), 'e', c('d', 'f'), c('foo','baz','bar'))

然后,您可以使用outerintersect来计算邻接矩阵:

adj <- outer(m,m,Vectorize(function(x,y) length(intersect(x,y))))

这是这个矩阵:

> adj
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    2    0    0    0
[2,]    2    3    0    1    0
[3,]    0    0    1    0    0
[4,]    0    1    0    2    0
[5,]    0    0    0    0    3

然后,使用igraph包,将矩阵转换为图形并提取组件:

cmp <- components(graph.adjacency(adj))

cmp$membership是将每个节点分配给组件:

> cmp$membership
[1] 1 1 2 1 3

您可以使用tapply找到组件的所有元素:

> tapply(m, cmp$membership, Reduce, f=union)
$`1`
[1] "a" "b" "c" "d" "f"

$`2`
[1] "e"

$`3`
[1] "foo" "baz" "bar"