在两个列表上应用outer()

时间:2014-05-15 15:01:21

标签: r outer-join

我有一个清单,说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。有没有想过这样做?

2 个答案:

答案 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