我有一个清单,说exm = list( elm1=c('a', 'b'), elm2=c('b', 'c', 'd'), elm3=c('b', 'c', 'd', 'e'))
。我想对exm
的两个元素的每个组合应用一个函数,例如length( intersect( exm$elm1, exm$elm2 ) )
。结果应该是对称矩阵。函数outer
似乎可以完成这项工作,但它仅适用于vector而不是list。有没有想过这样做?
答案 0 :(得分:3)
以下内容如何:
exm = list( elm1=c('a', 'b'), elm2=c('b', 'c', 'd'), elm3=c('b', 'c', 'd', 'e'))
#Use mapply to vectorise your function
int2 <- function(x,y) mapply(function(x,y) {length( intersect( x, y ) )},
exm[x], exm[y])
#Use outer on the indices of exm, rather than exm itself
s <- seq_along(exm)
outer(s,s,int2)
# [,1] [,2] [,3]
# [1,] 2 1 1
# [2,] 1 3 3
# [3,] 1 3 4
答案 1 :(得分:0)
这是另一种方法:
# Data
exm = list( elm1=c('a', 'b'), elm2=c('b', 'c', 'd'), elm3=c('b', 'c', 'd', 'e'))
# Set up possible comparisons
combinations <- data.frame(t(combn(names(exm), 2)))
# Caculate overlap
for (i in 1:nrow(combinations)){
combinations$length[[i]] <- length(intersect(exm[[combinations[i,1]]], exm[[combinations[i,2]]]))
}
# > combinations
# X1 X2 length
# 1 elm1 elm2 1
# 2 elm1 elm3 1
# 3 elm2 elm3 3
# Matrix output
m.out <- matrix(ncol=length(exm), nrow=length(exm), dimnames = list(names(exm),names(exm)))
# Fil in overlap figures
m.out[cbind(combinations$X1, combinations$X2)] <- combinations$length
m.out[cbind(combinations$X2, combinations$X1)] <- combinations$length
# Fill in length of vector itself as diagonal - if necessary
diag(m.out) <- unlist(lapply(exm, length))
# > m.out
# elm1 elm2 elm3
# elm1 2 1 1
# elm2 1 3 3
# elm3 1 3 4