r - 计算 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 有两项共同研究。
解决方案
我相信您正在寻找交叉研究的对称矩阵。
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
推荐阅读
- apache-kafka - 脚本仅在通过 SystemD 启动时挂起
- cmd - 使用 CMD 将文件从多个文件夹移动到父目录
- azure - Azure AKS:控制在缩减时应删除哪个节点
- group-by - PySpark Dataframe 中的 GroupBy 水平堆叠
- javascript - 如何定义异步函数?
- javascript - 如何使用带有登录详细信息的灯塔?
- javascript - 如何使用纯 JavaScript 更新所有子 ID
- c# - Nuget Hell:由于公钥差异,无法在 UWP 应用程序中引用 NuGet 包
- java - 使用 Keycloak 作为授权服务器,使用 Zuul 作为 API 网关
- pyspark - 在 pySpark 中定义自定义窗口函数