首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R中两个向量中重叠实例的计数

R中两个向量中重叠实例的计数
EN

Stack Overflow用户
提问于 2020-03-22 04:23:48
回答 2查看 765关注 0票数 0

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

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

代码语言:javascript
复制
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

我希望它能回来:

代码语言:javascript
复制
  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有两个共同的研究。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-22 05:07:42

我相信你在寻找一个交叉研究的对称矩阵。

代码语言:javascript
复制
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定义的名称

代码语言:javascript
复制
rownames(out) <- colnames(out) <- names(dfspl)
out
#   1 2 3
# 1 3 1 2
# 2 1 1 0
# 3 2 0 2

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

代码语言:javascript
复制
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将创建两个参数向量的扩展,并将它们同时传递给函数。例如,

代码语言:javascript
复制
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]> 

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

代码语言:javascript
复制
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,这是相同的结果),所以这有点低效.最好是过滤他们,只看上或下半部,并把它转移到另一个。

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

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2020-03-22 06:08:26

与@r2evans相同的想法,也是Base (口才稍差一点)(根据需要编辑):

代码语言:javascript
复制
# Create df using sample data: 

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

# Test for equality between the values in the metas vector and the rest of 
# of the values in the dataframe -- Construct symmetric matrix from vector: 

m1 <- diag(v1); m1[,1] <- m1[1,] <- v1 <- rowSums(data.frame(sapply(df$metas, `==`, 
                                                                    unique(unlist(df)))))

# Coerce matrix to dataframe setting the names as desired; dropping non matches:

df_2 <- setNames(data.frame(m1[which(rowSums(m1) > 0), which(colSums(m1) > 0)]),
                 paste0("v", 1:ncol(m1[which(rowSums(m1) > 0), which(colSums(m1) > 0)])))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60795913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档