有没有一种方法可以不包含特定组的重复项/重复项?

时间:2019-05-10 11:18:03

标签: r dplyr filtering data-manipulation

某些情况优先: 我正在使用包含健康相关数据的数据集。它包括治疗前后的问卷评分。但是,某些客户会再次出现在数据中以进行进一步处理。我在代码部分提供了数据的模拟示例。

我试图在dplyr上提出一个解决方案,因为这是我最熟悉的软件包,但是我没有实现我想要的。

#Example/mock data
   ClientNumber<-c("4355", "2231", "8894", "9002", "4355", "2231", "8894", "9002", "4355", "2231")
        Pre_Post<-c(1,1,1,1,2,2,2,2,1,1)
        QuestionnaireScore<-c(62,76,88,56,22,30, 35,40,70,71)
        df<-data.frame(ClientNumber, Pre_Post, QuestionnaireScore)
        df$ClientNumber<-as.character(df$ClientNumber)
        df$Pre_Post<-as.factor(df$Pre_Post)
        View(df)
#tried solution
df2<-df%>%
  group_by(ClientNumber)%>%
  filter( Pre_Post==1|Pre_Post==2)
#this doesn't work, or needs more code to it

如您所见,前四个客户编号都具有治疗前和治疗后的分数。很好但是,客户编号4355和2231再次出现在末尾(您可以说它们已经复发并开始新的治疗方法)。这两个客户没有治疗后分数。

  

我只想分析具有前和后得分的客户,因此我需要过滤已完成治疗的客户,而如果没有再次出现在治疗后得分的客户,则将其排除在数据之外。关于我提供的示例,我想包括前8个用于分析,而排除后两个,因为它们没有后期处理得分。

3 个答案:

答案 0 :(得分:1)

先输入arrange个客户编号,然后再输入group_by,最后使用dplyr::leaddplyr::lag进行过滤

library(dplyr)
df %>% arrange(ClientNumber) %>% group_by(ClientNumber) %>% 
       filter(Pre_Post==1 & lead(Pre_Post)==2 | Pre_Post==2 & lag(Pre_Post)==1)

# A tibble: 8 x 3
# Groups:   ClientNumber [4]
   ClientNumber Pre_Post QuestionnaireScore
   <fct>           <dbl>              <dbl>
1 2231                1                 76
2 2231                2                 30
3 4355                1                 62
4 4355                2                 22
5 8894                1                 88
6 8894                2                 35
7 9002                1                 56
8 9002                2                 40

答案 1 :(得分:1)

如果要妥善处理这些案件,可以尝试:

library(dplyr)

df %>%
  group_by(ClientNumber) %>%
  filter(!duplicated(Pre_Post) & n_distinct(Pre_Post) == 2)

  ClientNumber Pre_Post QuestionnaireScore
  <fct>           <dbl>              <dbl>
1 4355                1                 62
2 2231                1                 76
3 8894                1                 88
4 9002                1                 56
5 4355                2                 22
6 2231                2                 30
7 8894                2                 35
8 9002                2                 40

我不知道您是否真的需要使用n_distinct(),但是保留它不会有什么坏处。如果数据中存在前分数但没有后分数的案例,这将删除它们。

答案 2 :(得分:0)

另一个选择是为每个ClientNumber创建2个组,并仅选择其中有2行的那些组。

library(dplyr)

df %>%
  arrange(ClientNumber) %>%
  group_by(ClientNumber, group = cumsum(Pre_Post == 1)) %>%
  filter(n() == 2) %>%
  ungroup() %>%
  select(-group)

#  ClientNumber Pre_Post QuestionnaireScore
#    <chr>        <fct>          <dbl>
#1    2231         1               76
#2    2231         2               30
#3    4355         1               62
#4    4355         2               22
#5    8894         1               88
#6    8894         2               35
#7    9002         1               56
#8    9002         2               40

可以使用ave

在基R中翻译相同的内容
new_df <- df[order(df$ClientNumber), ]
subset(new_df, ave(Pre_Post,ClientNumber,cumsum(Pre_Post == 1),FUN = length) == 2)