R 如何在数据框中查找组之间共享的值?

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

我有一个整洁的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  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