如何根据另一列选择多个行?

时间:2019-05-19 14:34:32

标签: r

我有一个数据列,其中有许多列和行,并且有许多id,以下数据仅显示2个id。

id  treatment  
1   A          
1   B          
1   C          
1   D          
1   E          
2   A          
2   B         
2   C  

我想使用五种处理方式(A,B,C,D,E)获得id的子组。 因此,输出表将如下所示:

id  treatment
1   A          
1   B        
1   C           
1   D           
1   E   

非常感谢您。

6 个答案:

答案 0 :(得分:1)

要返回包含所有处理的ID组的子集,请执行以下操作:

install.packages("dplyr")
library(dplyr)

treatments <- c("A", "B", "C", "D", "E")

df %>% group_by(id) %>% filter(all(treatments %in% treatment))

#### OUTPUT ####

# A tibble: 5 x 2
# Groups:   id [1]
     id treatment
  <int> <fct>    
1     1 A        
2     1 B        
3     1 C        
4     1 D        
5     1 E        

这里的主要优点是它可以正确处理重复条件。也就是说,在一个ID组中您具有相同条件的可能性很小,例如:

# A tibble: 11 x 2
      id treatment
   <dbl> <chr>    
 1     1 A        
 2     1 A        
 3     1 B        
 4     1 C        
 5     1 D        
 6     1 E        
 7     2 A        
 8     2 A        
 9     2 B        
10     2 B        
11     2 C        

上面的代码将返回包含每个条件的任何组的所有观测值:

# A tibble: 6 x 2
# Groups:   id [1]
     id treatment
  <dbl> <chr>    
1     1 A        
2     1 A        
3     1 B        
4     1 C        
5     1 D        
6     1 E        

答案 1 :(得分:0)

这是一种超级简洁的方法:

 head(my.data)
  id treatment
1  1         A
2  1         B
3  1         C
4  1         D
5  1         E
6  2         A

group_by(my.data, id) %>% filter(n_distinct(treatment) == 5)
# A tibble: 5 x 2
# Groups:   id [1]
     id treatment     
  <int> <chr>     
1     1 A            
2     1 B            
3     1 C            
4     1 D            
5     1 E   

说明

在内部,n_distinct(treatment)对每个id类别中唯一值的实例进行计数,因为您是根据该列进行分组的。然后过滤器会保留发生5次的id

答案 2 :(得分:0)

以下是一个使用dplyr的选项。

编辑

这是一个更简洁的解决方案,下面是原始解决方案。这种较短的解决方案还删除了重复的行。 num.treatments硬编码为5,但可以根据需要进行设置。

library(dplyr)

# load your data
treatment.df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), treatment = c("A", "B", "C", "D", "E", "A", "B", "C")), class = "data.frame", row.names = c(NA, -8L))
num.treatments <- 5
unique(treatment.df[c("id", "treatment")]) %>%
  group_by(id) %>%
  filter(n() == num.treatments)

原始解决方案

library(dplyr)

# load your data
treatment.df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), treatment = c("A", "B", "C", "D", "E", "A", "B", "C")), class = "data.frame", row.names = c(NA, -8L))
treatment.df
##   id treatment
## 1  1         A
## 2  1         B
## 3  1         C
## 4  1         D
## 5  1         E
## 6  2         A
## 7  2         B
## 8  2         C

## Get IDs with a complete set of treatments
ids.with.all.treatments <-
  treatment.df %>%
  group_by(id, treatment) %>%
  summarise() %>%          # Get unique set if id/treatment pairs in cases of duplicates.
  summarise(cnt = n()) %>% # Summarise by 'id' to the count per id.
  filter(cnt == 5)         # Get items with the expected number of treatments


treatment.df %>%
  filter(id %in% ids.with.all.treatments$id)
##   id treatment
## 1  1         A
## 2  1         B
## 3  1         C
## 4  1         D
## 5  1         E

答案 3 :(得分:0)

还有dplyr的可能性:

df %>%
 group_by(id) %>%
 filter(grepl("A,B,C,D,E", paste(treatment, collapse = ","), fixed = TRUE))

     id treatment
  <int> <chr>    
1     1 A        
2     1 B        
3     1 C        
4     1 D        
5     1 E 

在此还考虑了排序,这意味着它可以过滤出A,B,C,D,E不接受治疗的情况。

如果顺序不重要,则可以先安排“处理”列:

df %>%
 group_by(id) %>%
 arrange(treatment, .by_group = TRUE) %>%
 filter(grepl("A,B,C,D,E", paste(treatment, collapse = ","), fixed = TRUE))

考虑到@gersht所示的情况,可以将其修改为:

df %>%
 group_by(id) %>%
 filter(grepl("A,B,C,D,E", paste(unique(treatment), collapse = ","), fixed = TRUE))

或者:

df %>%
 group_by(id) %>%
 arrange(treatment, .by_group = TRUE) %>%
 filter(grepl("A,B,C,D,E", paste(unique(treatment), collapse = ","), fixed = TRUE))

答案 4 :(得分:0)

我认为提供基本的R解决方案会很有趣,

DF = data.frame(id = c(rep(1,5),rep(2,3)), treatment = c('A','C','B','D','E','A','B','C'))

请注意,为了说明这种可能性,我在treatment中对顺序进行了稍微的排列。

do.call(rbind,
  lapply(split(DF,DF$id),
    function(X){
      if(identical(sort(unique(X$treatment)),c('A','B','C','D','E'))) X
      else NULL}))

我允许id可以接受多次相同的治疗,因为尚不清楚data.frame的其余部分看起来是什么样,以及id组的治疗可能无法排序。

答案 5 :(得分:0)

这是在基数R中使用<div className="row"> <div className='col-sm-3'> 的一种方法(借用@steveb的数据):

<div className="row">