Есть ли способ фильтрации, который не включает дубликаты / повторяющиеся записи по отдельным группам? - PullRequest
0 голосов
/ 10 мая 2019

Сначала немного контекста: я работаю с набором данных, который включает данные, связанные со здоровьем.Он включает в себя результаты анкетирования до и после лечения.Однако некоторые клиенты вновь появляются в данных для дальнейшего лечения.Я предоставил фиктивный пример данных в разделе кода.

Я попытался найти решение для 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 ]

1 голос
/ 10 мая 2019

Если эти случаи должны быть в порядке, вы можете попробовать:

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(), но сохранить его не помешает. Это удалит случаи, у которых есть предварительная оценка, но нет последующей оценки, если они существуют в данных.

1 голос
/ 10 мая 2019

Сначала arrange ClientNumbers, затем group_by и, наконец, фильтр с использованием dplyr::lead и dplyr::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
0 голосов
/ 10 мая 2019

Другой вариант - создать группы по 2 для каждого ClientNumber и выбрать только те группы, в которых есть 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

То же самое можно перевести в базу R, используя ave

new_df <- df[order(df$ClientNumber), ]
subset(new_df, ave(Pre_Post,ClientNumber,cumsum(Pre_Post == 1),FUN = length) == 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...