我正在尝试计算列表元素中的公共条目数:
temp<-list(element1=c("a","b","c"), element2=c("b","c","d"),
element3=c("d","e","f"), element4=c("a","c","z"))
要获得元素的所有成对组合之间的重叠,此函数有效:
calculate.overlap.2<-function(y){
pw<-combn(y,2,FUN=function(x)sum(x[[1]]%in%x[[2]]))
names(pw)<-combn(y,2,FUN=function(x)paste(names(x)[[1]],names(x)[[2]],sep="-"))
return(pw)
}
为了获得元素的所有三向组合之间的重叠,此函数有效:
calculate.overlap.3<-function(y){
pw<-combn(y,3,FUN=function(x)sum(x[[1]]%in%x[[2]]&x[[1]]%in%x[[3]]))
names(pw)<-combn(y,3,FUN=function(x) paste(names(x)[[1]],names(x)[[2]],names(x)[[3]],sep="-"))
return(pw)
}
但是从功能内部的数字可以看出,这不是一个优雅的解决方案。
将这两个函数概括为一个非常好,并且有一个函数将每个重叠检查中的元素作为输入。也就是说,number.of.elements.per.comparison=2
的输入相当于上面的calculate.overlap.2
,number.of.elements.per.comparison=3
的函数的输入将与calculate.overlap.3
相同。
我觉得有一个非常优雅的解决方案,但我看不到它。
答案 0 :(得分:6)
这是一种方法:
ix = lapply(seq_along(temp), function(u) combn(seq_along(temp), u))
lapply(ix, function(m){
res = apply(m,2, function(v) length(Reduce(intersect, temp[v])))
setNames(res, apply(m, 2, paste, collapse='-'))
})
#[[1]]
#1 2 3 4
#3 3 3 3
#[[2]]
#1-2 1-3 1-4 2-3 2-4 3-4
# 2 0 2 1 1 0
#[[3]]
#1-2-3 1-2-4 1-3-4 2-3-4
# 0 1 0 0
#[[4]]
#1-2-3-4
# 0
答案 1 :(得分:6)
calculate.overlap <- function(y, i){
pw <- combn(seq_along(y), i, FUN= function(x) {
res <- length(Reduce(intersect, y[x]))
names(res) <- paste(names(y[x]), collapse = "-")
res
}, simplify = FALSE)
do.call(c, pw)
}
calculate.overlap(temp, 3)
#element1-element2-element3 element1-element2-element4 element1-element3-element4 element2-element3-element4
# 0 1 0 0
答案 2 :(得分:0)
在包VennDiagram
中,有一个名为calculate.overlap
的函数就是这样做的。如果需要查看,您甚至可以查阅列表并查看每个交叉点中的哪些元素。您可以将列表与最多5个子列表重叠。
指向包https://cran.r-project.org/web/packages/VennDiagram/index.html
的链接