使用Dplyr" group_by"创建群组然后使用Stringr查找组之间的差异

时间:2016-11-14 23:27:55

标签: r dplyr stringr

使用下面的示例,我想通过CaseWorker对客户进行数据框分组,然后为每个客户端组确定是否在"任务"与" Task2"中的任务列表相同。

如果每个任务都在" Task2"我会很高兴,简单的真假,或者更好。但不是"任务"可以提取并显示在新列或数据框中。

所以基本上我需要确保"任务"和"任务2"包含每个客户的相同条目。

如果可能的话,我想坚持使用Dplyr和Stringr,或者至少留在Tidyverse内。我在想那里使用" group_by"和" str_detect"或者其他一些Stringr功能,以优雅的方式实现这一目标。

CaseWorker<-c("John","John","John","John","John","John","Melanie","Melanie","Melanie","Melanie","Melanie","Melanie")
Client<-c("Chris","Chris","Chris","Tom","Tom","Tom","Valerie","Valerie","Valerie","Tim","Tim","Tim")
Task<-c("Feed cat","Make dinner","Iron shirt","Make dinner","Do homework","Make lunch","Make dinner","Feed cat","Buy groceries","Do homework","Iron shirt","Make lunch")
Task2<-c("Feed cat","Make dinner","Iron shirt","Make dinner","Do homework","Feed cat","Make dinner","Feed cat","Iron shirt","Do homework","Iron shirt","Make lunch")
Df<-data.frame(CaseWorker,Client,Task,Task2)

4 个答案:

答案 0 :(得分:2)

看看这是不是你想要的。

首先,查看Task是否与Task2匹配。如果不是,请将Task2作为新变量返回。我将其存储到新数据框df2

df2 <- Df %>% 
    mutate(match = Task == Task2,
           non_match = ifelse(!match, Task2, "")) 
df2

#    CaseWorker  Client          Task       Task2 match  non_match
# 1        John   Chris      Feed cat    Feed cat  TRUE           
# 2        John   Chris   Make dinner Make dinner  TRUE           
# 3        John   Chris    Iron shirt  Iron shirt  TRUE           
# 4        John     Tom   Make dinner Make dinner  TRUE           
# 5        John     Tom   Do homework Do homework  TRUE           
# 6        John     Tom    Make lunch    Feed cat FALSE   Feed cat
# 7     Melanie Valerie   Make dinner Make dinner  TRUE           
# 8     Melanie Valerie      Feed cat    Feed cat  TRUE           
# 9     Melanie Valerie Buy groceries  Iron shirt FALSE Iron shirt
# 10    Melanie     Tim   Do homework Do homework  TRUE           
# 11    Melanie     Tim    Iron shirt  Iron shirt  TRUE           
# 12    Melanie     Tim    Make lunch  Make lunch  TRUE           

然后summarise结果,以查看单个CaseWorker / Client对是否与所有条目匹配。

df2 %>% 
   group_by(CaseWorker, Client) %>% 
   summarise(n = n(),
             matches = sum(match),
             all_match = n == matches)

#   CaseWorker  Client     n matches all_match
#        <chr>   <chr> <int>   <int>     <lgl>
# 1       John   Chris     3       3      TRUE
# 2       John     Tom     3       2     FALSE
# 3    Melanie     Tim     3       3      TRUE
# 4    Melanie Valerie     3       2     FALSE

如果您需要原始数据集中的all_match变量,您当然可以将其合并回数据框。

答案 1 :(得分:1)

您只需dplyr并使用%in%

即可完成此操作
Df %>% 
  group_by(CaseWorker,Client) %>% 
  mutate(Check = Task %in% Task2) 

这取决于确切的案例匹配,如果您担心以下情况:

 Df %>% 
  group_by(CaseWorker,Client) %>% 
  rowwise() %>% 
  mutate(Check = grepl(Task, Task2, ignore.case = TRUE)) 

但你必须在mutate之前使用rowwise来解决grepl(或大多数R函数)的向量化性质

答案 2 :(得分:0)

如果您想使用stringr包。以下内容也可以为您服务。

Df %>% 
     group_by(CaseWorker,Client) %>% 
     mutate(Check=str_detect(as.character(Task),as.character(Task2))

答案 3 :(得分:0)

这可能只是我误解了这个问题,但我认为如果你想要的只是Task与Task2不匹配的记录,你可能会过度复杂化。

> Df[which(Df$Task != Df$Task2),]

===  ==========  =======  =============  ==========
\    CaseWorker  Client   Task           Task2     
===  ==========  =======  =============  ==========
6    John        Tom      Make lunch     Feed cat  
9    Melanie     Valerie  Buy groceries  Iron shirt
===  ==========  =======  =============  ==========