我正在学习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
)
是否可以聚合行,但首先检查它们是否应该聚合?或者是我的问题的另一种解决方案?
答案 0 :(得分:1)
这实际上是一个棘手的问题;您将需要找到无向图的组件,其中数据的每一行都是一个节点,如果它们有任何元素重叠,则它们之间有边。
首先,您应该使用strsplit()
清理数据,这将为您提供一系列集合,类似于:
m <- list(c('a','b','c'), c('b','c','d'), 'e', c('d', 'f'), c('foo','baz','bar'))
然后,您可以使用outer
和intersect
来计算邻接矩阵:
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"