如何识别和计算 R 中的交集项
How to identify and tally intersection items in R
我有一个数据框,它以三种颜色 类 显示成员资格。 数字是指唯一的 ID。一个ID可以是一个组或多个组的一部分。
dat <- data.frame(BLUE = c(1, 2, 3, 4, 6, NA),
RED = c(2, 3, 6, 7, 9, 13),
GREEN = c(4, 6, 8, 9, 10, 11))
或视觉参考:
BLUE RED GREEN
1 2 4
2 3 6
3 6 8
4 7 9
6 9 10
NA 13 11
我需要识别和统计个人和跨组成员资格(即有多少 ID 仅是红色的,有多少 ID 是红色和蓝色的,等等)我想要的输出如下。请注意,ID 列仅供参考,该列不会出现在预期的输出中。
COLOR TOTAL IDs (reference only, not needed in final output)
RED 2 (7, 13)
BLUE 1 (1)
GREEN 3 (8, 10, 11)
RED, BLUE 3 (2, 3, 6)
RED, GREEN 2 (6, 9)
BLUE, GREEN 2 (4, 6)
RED, BLUE, GREEN 1 (6)
有人知道在 R 中执行此操作的有效方法吗?谢谢!
您可以使用 venn
库(尤其适用于数据中没有 NA 的情况):
venn_table <- venn(as.list(dat))
BLUE RED GREEN counts
0 0 0 0
GREEN 0 0 1 3
RED 0 1 0 2
RED:GREEN 0 1 1 1
BLUE 1 0 0 2
BLUE:GREEN 1 0 1 1
BLUE:RED 1 1 0 2
BLUE:RED:GREEN 1 1 1 1
并且:
attr(venn_table, "intersections")
$GREEN
[1] 8 10 11
$RED
[1] 7 13
$`RED:GREEN`
[1] 9
$BLUE
[1] 1 NA
$`BLUE:GREEN`
[1] 4
$`BLUE:RED`
[1] 2 3
$`BLUE:RED:GREEN`
[1] 6
要同时包含 ID:
data.frame(venn_table[2:nrow(venn_table), ],
ID = do.call("rbind", lapply(attr(venn_table, "intersections"), paste0, collapse = ",")))
BLUE RED GREEN counts ID
GREEN 0 0 1 3 8,10,11
RED 0 1 0 2 7,13
RED:GREEN 0 1 1 1 9
BLUE 1 0 0 2 1,NA
BLUE:GREEN 1 0 1 1 4
BLUE:RED 1 1 0 2 2,3
BLUE:RED:GREEN 1 1 1 1 6
处理 NA 的一种方法:
venn_table2 <- data.frame(venn_table[2:nrow(venn_table), length(venn_table), drop = FALSE],
ID = do.call("rbind", lapply(attr(venn_table, "intersections"), paste0, collapse = ",")))
counts <- venn_table2[1] - with(venn_table2, lengths(regmatches(ID, gregexpr("NA", ID))))
counts
GREEN 3
RED 2
RED:GREEN 1
BLUE 1
BLUE:GREEN 1
BLUE:RED 2
BLUE:RED:GREEN 1
处理 NA 的更优雅的方法可能是(基于@M-- 的评论):
print(venn(Map(function(x) x[!is.na(x)], as.list(dat))))
BLUE RED GREEN counts
0 0 0 0
GREEN 0 0 1 3
RED 0 1 0 2
RED:GREEN 0 1 1 1
BLUE 1 0 0 1
BLUE:GREEN 1 0 1 1
BLUE:RED 1 1 0 2
BLUE:RED:GREEN 1 1 1 1
library(dplyr)
library(tidyr)
cbind(dat, row = 1:6) %>%
gather(COLOR, IDs, -row) %>%
group_by(IDs) %>%
nest(COLOR, .key="COLOR") %>%
mutate(COLOR = sapply(COLOR, as.character)) %>%
drop_na %>%
group_by(COLOR) %>%
add_count(name="TOTAL") %>%
group_by(COLOR, TOTAL) %>%
nest(IDs, .key = "IDs") %>%
as.data.frame
#> COLOR TOTAL IDs
#> 1 BLUE 1 1
#> 2 c("BLUE", "RED") 2 2, 3
#> 3 c("BLUE", "GREEN") 1 4
#> 4 c("BLUE", "RED", "GREEN") 1 6
#> 5 RED 2 7, 13
#> 6 c("RED", "GREEN") 1 9
#> 7 GREEN 3 8, 10, 11
venn
包中有一个更常规的方法来处理NA
:
library(purrr)
library(magrittr)
library(venn)
as.list(dat) %>%
map(discard, is.na) %>%
compact() %>%
venn() %>%
print
#> BLUE RED GREEN counts
#> 0 0 0 0
#> GREEN 0 0 1 3
#> RED 0 1 0 2
#> RED:GREEN 0 1 1 1
#> BLUE 1 0 0 1
#> BLUE:GREEN 1 0 1 1
#> BLUE:RED 1 1 0 2
#> BLUE:RED:GREEN 1 1 1 1
根据这个 answer,R
中的 venn
图还有许多其他包。
例如,VennDiagram::venn.diagram
包有一个 na
变量,它得到 stop
、remove
和 none
。所以,这里我们会使用 remove
;然而,它只会给我们图表而不是 table。您可以在其他包中探索其他可能性。
我有一个数据框,它以三种颜色 类 显示成员资格。 数字是指唯一的 ID。一个ID可以是一个组或多个组的一部分。
dat <- data.frame(BLUE = c(1, 2, 3, 4, 6, NA),
RED = c(2, 3, 6, 7, 9, 13),
GREEN = c(4, 6, 8, 9, 10, 11))
或视觉参考:
BLUE RED GREEN
1 2 4
2 3 6
3 6 8
4 7 9
6 9 10
NA 13 11
我需要识别和统计个人和跨组成员资格(即有多少 ID 仅是红色的,有多少 ID 是红色和蓝色的,等等)我想要的输出如下。请注意,ID 列仅供参考,该列不会出现在预期的输出中。
COLOR TOTAL IDs (reference only, not needed in final output)
RED 2 (7, 13)
BLUE 1 (1)
GREEN 3 (8, 10, 11)
RED, BLUE 3 (2, 3, 6)
RED, GREEN 2 (6, 9)
BLUE, GREEN 2 (4, 6)
RED, BLUE, GREEN 1 (6)
有人知道在 R 中执行此操作的有效方法吗?谢谢!
您可以使用 venn
库(尤其适用于数据中没有 NA 的情况):
venn_table <- venn(as.list(dat))
BLUE RED GREEN counts
0 0 0 0
GREEN 0 0 1 3
RED 0 1 0 2
RED:GREEN 0 1 1 1
BLUE 1 0 0 2
BLUE:GREEN 1 0 1 1
BLUE:RED 1 1 0 2
BLUE:RED:GREEN 1 1 1 1
并且:
attr(venn_table, "intersections")
$GREEN
[1] 8 10 11
$RED
[1] 7 13
$`RED:GREEN`
[1] 9
$BLUE
[1] 1 NA
$`BLUE:GREEN`
[1] 4
$`BLUE:RED`
[1] 2 3
$`BLUE:RED:GREEN`
[1] 6
要同时包含 ID:
data.frame(venn_table[2:nrow(venn_table), ],
ID = do.call("rbind", lapply(attr(venn_table, "intersections"), paste0, collapse = ",")))
BLUE RED GREEN counts ID
GREEN 0 0 1 3 8,10,11
RED 0 1 0 2 7,13
RED:GREEN 0 1 1 1 9
BLUE 1 0 0 2 1,NA
BLUE:GREEN 1 0 1 1 4
BLUE:RED 1 1 0 2 2,3
BLUE:RED:GREEN 1 1 1 1 6
处理 NA 的一种方法:
venn_table2 <- data.frame(venn_table[2:nrow(venn_table), length(venn_table), drop = FALSE],
ID = do.call("rbind", lapply(attr(venn_table, "intersections"), paste0, collapse = ",")))
counts <- venn_table2[1] - with(venn_table2, lengths(regmatches(ID, gregexpr("NA", ID))))
counts
GREEN 3
RED 2
RED:GREEN 1
BLUE 1
BLUE:GREEN 1
BLUE:RED 2
BLUE:RED:GREEN 1
处理 NA 的更优雅的方法可能是(基于@M-- 的评论):
print(venn(Map(function(x) x[!is.na(x)], as.list(dat))))
BLUE RED GREEN counts
0 0 0 0
GREEN 0 0 1 3
RED 0 1 0 2
RED:GREEN 0 1 1 1
BLUE 1 0 0 1
BLUE:GREEN 1 0 1 1
BLUE:RED 1 1 0 2
BLUE:RED:GREEN 1 1 1 1
library(dplyr)
library(tidyr)
cbind(dat, row = 1:6) %>%
gather(COLOR, IDs, -row) %>%
group_by(IDs) %>%
nest(COLOR, .key="COLOR") %>%
mutate(COLOR = sapply(COLOR, as.character)) %>%
drop_na %>%
group_by(COLOR) %>%
add_count(name="TOTAL") %>%
group_by(COLOR, TOTAL) %>%
nest(IDs, .key = "IDs") %>%
as.data.frame
#> COLOR TOTAL IDs
#> 1 BLUE 1 1
#> 2 c("BLUE", "RED") 2 2, 3
#> 3 c("BLUE", "GREEN") 1 4
#> 4 c("BLUE", "RED", "GREEN") 1 6
#> 5 RED 2 7, 13
#> 6 c("RED", "GREEN") 1 9
#> 7 GREEN 3 8, 10, 11
venn
包中有一个更常规的方法来处理NA
:
library(purrr)
library(magrittr)
library(venn)
as.list(dat) %>%
map(discard, is.na) %>%
compact() %>%
venn() %>%
print
#> BLUE RED GREEN counts
#> 0 0 0 0
#> GREEN 0 0 1 3
#> RED 0 1 0 2
#> RED:GREEN 0 1 1 1
#> BLUE 1 0 0 1
#> BLUE:GREEN 1 0 1 1
#> BLUE:RED 1 1 0 2
#> BLUE:RED:GREEN 1 1 1 1
根据这个 answer,R
中的 venn
图还有许多其他包。
例如,VennDiagram::venn.diagram
包有一个 na
变量,它得到 stop
、remove
和 none
。所以,这里我们会使用 remove
;然而,它只会给我们图表而不是 table。您可以在其他包中探索其他可能性。