Primero un poco de contexto: estoy trabajando con un conjunto de datos que incluye datos relacionados con la salud. Incluye puntajes de cuestionarios antes y después del tratamiento. Sin embargo, algunos clientes reaparecen dentro de los datos para un tratamiento adicional. He proporcionado un ejemplo simulado de los datos en la sección de código.
He intentado encontrar una solución en dplyr, ya que este es el paquete con el que estoy más familiarizado, pero no logré lo que quería.
#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
Como puede ver, los primeros cuatro números de clientes tienen un puntaje previo y posterior al tratamiento. Esto es bueno. Sin embargo, los números de cliente 4355 y 2231 aparecen nuevamente al final (se podría decir que han recaído y han comenzado un nuevo tratamiento). Estos dos clientes no tienen una puntuación posterior al tratamiento.
Solo quiero analizar a los clientes que tienen un puntaje previo y posterior, por lo tanto, necesito filtrar a los clientes que han completado el tratamiento, excluyendo aquellos que no tienen un puntaje posterior al tratamiento si han aparecido nuevamente en los datos. En relación con el ejemplo que he proporcionado, quiero incluir los primeros 8 para el análisis, excluyendo los dos últimos, ya que no tienen una puntuación posterior al tratamiento.
3 respuestas
Otra opción es crear grupos de 2 por cada ClientNumber
y seleccionar solo aquellos grupos que tengan 2 filas.
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
Lo mismo se puede traducir en la base R usando ave
new_df <- df[order(df$ClientNumber), ]
subset(new_df, ave(Pre_Post,ClientNumber,cumsum(Pre_Post == 1),FUN = length) == 2)
Si estos casos deben mantenerse en orden, podría intentar:
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
No sé si realmente necesitas usar n_distinct()
pero no te hará daño mantenerlo. Esto eliminará los casos que tengan una calificación previa pero no una calificación posterior si existen en los datos.
Primero arrange
ClientNumbers luego group_by
y finalmente filtrar usando dplyr::lead
y 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
Preguntas relacionadas
Nuevas preguntas
r
R es un entorno de software y lenguaje de programación de código abierto y gratuito para computación estadística, bioinformática, visualización y computación en general. Proporcione ejemplos mínimos y reproducibles junto con el resultado deseado. Use dput () para los datos y especifique todos los paquetes no base con llamadas a library (). No incruste imágenes para datos o código, use bloques de código con sangría en su lugar. Para preguntas relacionadas con estadísticas, use https://stats.stackexchange.com.