【问题标题】:Is there a way to filter that does not include duplicates/repeated entries by particular groups?有没有办法过滤不包括特定组的重复/重复条目?
【发布时间】:2019-05-10 11:18:02
【问题描述】:

首先是一些上下文: 我正在使用一个包含健康相关数据的数据集。它包括治疗前后的问卷分数。但是,一些客户重新出现在数据中以进行进一步处理。我在代码部分提供了数据的模拟示例。

我试图在 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 个进行分析,同时排除后两个,因为它们没有治疗后分数。

【问题讨论】:

  • 您能粘贴您预期的数据应该是什么样子吗?

标签: r dplyr filtering data-manipulation


【解决方案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(),但保留它不会有什么坏处。这将删除具有预评分但没有后评分的案例(如果它们存在于数据中)。

【讨论】:

  • 这很好用。它保留了订单,并且似乎已经删除了我想要删除的 ClientNumbers。非常感谢!
【解决方案2】:

首先arrangeClientNumbers 然后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

【讨论】:

  • 这也是一种享受。我喜欢这个解决方案的地方在于它以一种允许我检查以检查前后结果的方式对行进行排序;对观察数据非常有帮助。非常感谢!
【解决方案3】:

另一个选项是为每个 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在base R中翻译

new_df <- df[order(df$ClientNumber), ]
subset(new_df, ave(Pre_Post,ClientNumber,cumsum(Pre_Post == 1),FUN = length) == 2)

【讨论】:

  • dplyr 解决方案效果很好。我喜欢它以一种允许检查前后检查的方式对客户进行排序,这真的很方便。谢谢!
猜你喜欢
  • 2019-09-28
  • 2018-02-04
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
相关资源
最近更新 更多