某些情况优先: 我正在使用包含健康相关数据的数据集。它包括治疗前后的问卷评分。但是,某些客户会再次出现在数据中以进行进一步处理。我在代码部分提供了数据的模拟示例。
我试图在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个用于分析,而排除后两个,因为它们没有后期处理得分。
答案 0 :(得分:1)
先输入arrange
个客户编号,然后再输入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
答案 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
new_df <- df[order(df$ClientNumber), ]
subset(new_df, ave(Pre_Post,ClientNumber,cumsum(Pre_Post == 1),FUN = length) == 2)