R 如何在数据框中查找组之间共享的值?
我有一个整洁的data.frame,它有两列:exp和val。我想找出在所有不同的实验中,val的哪些值是共享的R 如何在数据框中查找组之间共享的值?,r,dataframe,dplyr,R,Dataframe,Dplyr,我有一个整洁的data.frame,它有两列:exp和val。我想找出在所有不同的实验中,val的哪些值是共享的 df <- data.frame(exp = c('A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'), val = c(10, 20, 15, 10, 10, 15, 99, 2, 15, 20, 10, 4)) df exp val 1 A 10 2 A
df <- data.frame(exp = c('A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'),
val = c(10, 20, 15, 10, 10, 15, 99, 2, 15, 20, 10, 4))
df
exp val
1 A 10
2 A 20
3 A 15
4 A 10
5 B 10
6 B 15
7 B 99
8 B 2
9 C 15
10 C 20
11 C 10
12 C 4
或数据框上的一列,说明该值是否共享:
exp val shared
<fct> <dbl> <lgl>
1 A 10 TRUE
2 A 20 FALSE
3 A 15 TRUE
4 A 10 TRUE
5 B 10 TRUE
6 B 15 TRUE
7 B 99 FALSE
8 B 2 FALSE
9 C 15 TRUE
10 C 20 FALSE
11 C 10 TRUE
12 C 4 FALSE
我能找到一个答案,见下面的自我回答,但这似乎是一个足够常见的问题,一定有比我想出的真正骇人的解决方案更好的方法
我试图在dplyr中解决这个问题,因为这是我所熟悉的,但我对任何一种解决方案都感兴趣。我们可以逐行查看data.frame,并计算在向量df$val中找到该行值的次数 为了处理可能的重复值,我们必须使用group_by%>%distinct来删除组内val的重复值。但是,为了得到作为向量的val值,我们需要将%>%selectval%>%unlist解组,这似乎不必要地复杂 最后,我们可以检查该值所在的组数是否等于组总数
df %>%
rowwise() %>%
mutate(num_groups = sum(group_by(., exp) %>%
distinct(val) %>%
ungroup() %>%
select(val) %>%
unlist() %in% val),
shared = num_groups == length(unique(.$exp)))
# A tibble: 12 x 4
exp val num_groups shared
<fct> <dbl> <int> <lgl>
1 A 10 3 TRUE
2 A 20 2 FALSE
3 A 15 3 TRUE
4 A 10 3 TRUE
5 B 10 3 TRUE
6 B 15 3 TRUE
7 B 99 1 FALSE
8 B 2 1 FALSE
9 C 15 3 TRUE
10 C 20 2 FALSE
11 C 10 3 TRUE
12 C 4 1 FALSE
或者,您可以按val分组,然后检查该val的不同exp数是否等于不同exp的数据帧级别数:
使用base R,您可以使用表:
您还可以执行以下操作:
df %>%
mutate(s = val %in% as.numeric(colnames(a<-table(df))[colSums(a>0)==nrow(a)]))
exp val s
1 A 10 TRUE
2 A 20 FALSE
3 A 15 TRUE
4 A 10 TRUE
5 B 10 TRUE
6 B 15 TRUE
7 B 99 FALSE
8 B 2 FALSE
9 C 15 TRUE
10 C 20 FALSE
11 C 10 TRUE
12 C 4 FALSE
下面是另一个基本的R解决方案:
x <- split(df$val, df$exp)
Reduce(intersect, x)
## [1] 10 15
或者作为。numericnamesx谢谢!我知道一定有这么简单的事情。有什么理由我不能用.$exp替换df$exp以使其更便于携带吗?当我尝试它时,它似乎给出了相同的结果。是的。您可以使用.$exp,它应该以同样的方式工作。
as.numeric(colnames(a<-table(df))[colSums(a>0)==nrow(a)])
[1] 10 15
df %>%
mutate(s = val %in% as.numeric(colnames(a<-table(df))[colSums(a>0)==nrow(a)]))
exp val s
1 A 10 TRUE
2 A 20 FALSE
3 A 15 TRUE
4 A 10 TRUE
5 B 10 TRUE
6 B 15 TRUE
7 B 99 FALSE
8 B 2 FALSE
9 C 15 TRUE
10 C 20 FALSE
11 C 10 TRUE
12 C 4 FALSE
x <- split(df$val, df$exp)
Reduce(intersect, x)
## [1] 10 15