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

时间:2018-08-14 19:32:23

标签: r dataframe dplyr

我有一个整齐的data.frame,其中有两列:expval。我想找出所有不同实验之间共享的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

预期结果可以是值的向量:

10, 15

或数据框上的一列,指示是否共享该值:

   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中解决此问题,但是我对任何一种解决方案都感兴趣。

4 个答案:

答案 0 :(得分:2)

或者您可以按val分组,然后检查该exp的不同val的数量是否等于不同exp的数据帧级数量:< / p>

df %>% 
    group_by(val) %>% 
    mutate(shared = n_distinct(exp) == n_distinct(.$exp))
    # notice the first exp refers to exp for each group while .$exp refers 
    # to the overall exp column in the data frame

# A tibble: 12 x 3
# Groups:   val [6]
#   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

答案 1 :(得分:2)

使用基数R可以使用table

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

答案 2 :(得分:2)

这是另一个基本的R解决方案:

  x <-split(df $ val,df $ exp)
减少(相交,x)
## [1] 10 15
 

答案 3 :(得分:0)

我们可以逐行遍历data.frame并计算在向量df$val中发现该行的值的次数。

要处理可能的重复值,我们必须使用group_by %>% distinct来删除组内val的重复值。但是,为了仅将val的值作为向量,我们需要ungroup %>% select(val) %>% 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