首页 > 解决方案 > 计算 R 中两个向量中重叠的实例

问题描述

我希望创建一个矩阵,显示基于第二个变量的分组变量的重叠值实例的计数。具体来说,我希望确定主要研究在元分析中重叠的程度,以创建网络图。

所以,在这个例子中,我有三项荟萃分析,其中包括三项主要研究的一部分。

df <- data.frame(metas = c(1,1,1,2,3,3), studies = c(1,3,2,1,2,3))

   metas studies
1     1    1
2     1    3
3     1    2
4     2    1
5     3    2
6     3    3

我希望它返回:

  v1 v2 v3
1  3  1  2
2  1  1  0
3  2  0  2

第 1 行第 1 列中的值表明 Meta 分析 1 有三项与其自身相同的研究(即,它包括三项研究)。第 1 行第 2 列表明 Meta 分析 1 与 Meta 分析 2 有一项共同研究。第 1 行第 3 列表明 Meta 分析 1 与 Meta 分析 3 有两项共同研究。

标签: roverlap

解决方案


我相信您正在寻找交叉研究的对称矩阵。

dfspl <- split(df$studies, df$metas)
out <- outer(seq_along(dfspl), seq_along(dfspl),
             function(a, b) lengths(Map(intersect, dfspl[a], dfspl[b])))
out
#      [,1] [,2] [,3]
# [1,]    3    1    2
# [2,]    1    1    0
# [3,]    2    0    2

如果您需要它们的名称,您可以使用以下定义的名称df$metas

rownames(out) <- colnames(out) <- names(dfspl)
out
#   1 2 3
# 1 3 1 2
# 2 1 1 0
# 3 2 0 2

如果您需要定义为的名称v加上元名称,请使用

rownames(out) <- colnames(out) <- paste0("v", names(dfspl))
out
#    v1 v2 v3
# v1  3  1  2
# v2  1  1  0
# v3  2  0  2

如果您需要了解这是在做什么,请outer创建两个参数向量的扩展,并将它们一次全部传递给函数。例如,

outer(seq_along(dfspl), seq_along(dfspl), function(a, b) { browser(); 1; })
# Called from: FUN(X, Y, ...)
debug at #1: [1] 1
# Browse[2]> 
a
# [1] 1 2 3 1 2 3 1 2 3
# Browse[2]> 
b
# [1] 1 1 1 2 2 2 3 3 3
# Browse[2]> 

我们最终想要做的是找到每对研究的交集。

dfspl[[1]]
# [1] 1 3 2
dfspl[[3]]
# [1] 2 3
intersect(dfspl[[1]], dfspl[[3]])
# [1] 3 2
length(intersect(dfspl[[1]], dfspl[[3]]))
# [1] 2

诚然,我们做了两次(一次用于 1 和 3,一​​次用于 3 和 1,这是相同的结果),所以这有点低效......最好过滤它们只看上部或下半部分并将其转移到另一部分。


编辑了一个更有效的过程(只计算每个交集对一次,从不计算自交集。)

eg <- expand.grid(a = seq_along(dfspl), b = seq_along(dfspl))
eg <- eg[ eg$a < eg$b, ]
eg
#   a b
# 4 1 2
# 7 1 3
# 8 2 3
lens <- lengths(Map(intersect, dfspl[eg$a], dfspl[eg$b]))
lens
# 1 1 2       ## btw, these are just names, from eg$a
# 1 2 0 
out <- matrix(nrow = length(dfspl), ncol = length(dfspl))
out[ cbind(eg$a, eg$b) ] <- lens
out
#      [,1] [,2] [,3]
# [1,]   NA    1    2
# [2,]   NA   NA    0
# [3,]   NA   NA   NA
out[ lower.tri(out) ] <- out[ upper.tri(out) ]
diag(out) <- lengths(dfspl)
out
#      [,1] [,2] [,3]
# [1,]    3    1    2
# [2,]    1    1    0
# [3,]    2    0    2

推荐阅读