vacio una tabla filtrar filas eliminar elegir datos data crear contar como columnas columna agregar r sum aggregate-functions feature-extraction feature-selection

una - Cómo realizar recuentos consecutivos de columna por grupo condicionalmente en otra columna



eliminar columnas en r (4)

Estoy intentando obtener recuentos consecutivos de la columna Noshow agrupada por la columna PatientID. El siguiente código que estoy usando está muy cerca de los resultados que deseo alcanzar. Sin embargo, usar la función suma devuelve la suma de todo el grupo. Me gustaría que la función de suma solo sume la fila actual y solo las filas que tienen un ''1'' por encima. Básicamente, estoy tratando de contar la cantidad consecutiva de veces que un paciente muestra su cita para cada fila y luego se restablece a 0 cuando se muestran. Parece que solo se deben realizar algunos ajustes en mi código de abajo. Sin embargo, parece que no puedo encontrar la respuesta en este sitio.

transform(df, ConsecNoshows = ifelse(Noshow == 0, 0, ave(Noshow, PatientID, FUN = sum)))

El código anterior produce el siguiente resultado:

#Source: local data frame [12 x 3] #Groups: ID [2] # # PatientID Noshow ConsecNoshows # <int> <int> <int> #1 1 0 0 #2 1 1 4 #3 1 0 0 #4 1 1 4 #5 1 1 4 #6 1 1 4 #7 2 0 0 #8 2 0 0 #9 2 1 3 #10 2 1 3 #11 2 0 0 #12 2 1 3

Esto es lo que deseo:

#Source: local data frame [12 x 3] #Groups: ID [2] # # PatientID Noshow ConsecNoshows # <int> <int> <int> #1 1 0 0 #2 1 1 0 #3 1 0 1 #4 1 1 0 #5 1 1 1 #6 1 1 2 #7 2 0 0 #8 2 0 0 #9 2 1 0 #10 2 1 1 #11 2 0 2 #12 2 1 0

[ACTUALIZAR] Me gustaría que el recuento consecutivo se compensara con una fila hacia abajo.

¡Gracias por cualquier ayuda que pueda ofrecer con anticipación!


Crearía una función auxiliar para luego usar la implementación con la que se sienta más cómodo:

sum0 <- function(x) {x[x == 1]=sequence(with(rle(x), lengths[values == 1]));x} #base R transform(df1, Consec = ave(Noshow, PatientID, FUN=sum0)) #dplyr library(dplyr) df1 %>% group_by(PatientID) %>% mutate(Consec=sum0(Noshow)) #data.table library(data.table) setDT(df1)[, Consec := sum0(Noshow), by = PatientID] # PatientID Noshow Consec # <int> <int> <int> # 1 1 0 0 # 2 1 1 1 # 3 1 0 0 # 4 1 1 1 # 5 1 1 2 # 6 1 1 3 # 7 2 0 0 # 8 2 0 0 # 9 2 1 1 # 10 2 1 2 # 11 2 0 0 # 12 2 1 1


La forma más sencilla de agrupar valores consecutivos es usar rleid de data.table , aquí hay una opción del paquete data.table , donde agrupa los datos por PatientID y también la variable Noshow . Y también necesita la función cumsum para obtener una suma acumulativa de la variable Noshow lugar de la sum :

library(data.table) setDT(df)[, ConsecNoshows := ifelse(Noshow == 0, 0, cumsum(Noshow)), .(PatientID, rleid(Noshow))] df # PatientID Noshow ConsecNoshows # 1: 1 0 0 # 2: 1 1 1 # 3: 1 0 0 # 4: 1 1 1 # 5: 1 1 2 # 6: 1 1 3 # 7: 2 0 0 # 8: 2 0 0 # 9: 2 1 1 #10: 2 1 2 #11: 2 0 0 #12: 2 1 1


Podemos usar rle desde la base R (sin paquetes usados). Usando ave , agrupamos por ''PatientID'', obtenemos el nombre de ''Noshow'', multiplicamos la sequence de ''longitudes'' por los ''valores'' replicados por ''lengths'' para obtener el resultado esperado.

helperfn <- function(x) with(rle(x), sequence(lengths) * rep(values, lengths)) df$ConsecNoshows <- with(df, ave(Noshow, PatientID, FUN = helperfn)) df$ConsecNoshows #[1] 0 1 0 1 2 3 0 0 1 2 0 1

Como el OP parece estar usando ''tbl_df'', una solución en dplyr sería

library(dplyr) df %>% group_by(PatientID) %>% mutate(ConsecNoshows = helperfn(Noshow)) # PatientID Noshow ConsecNoshows # <int> <int> <int> #1 1 0 0 #2 1 1 1 #3 1 0 0 #4 1 1 1 #5 1 1 2 #6 1 1 3 #7 2 0 0 #8 2 0 0 #9 2 1 1 #10 2 1 2 #11 2 0 0 #12 2 1 1


Y aquí hay otro enfoque data.table (similar)

library(data.table) setDT(df)[, ConsecNoshows := seq(.N) * Noshow, by = .(PatientID, rleid(Noshow))] df # PatientID Noshow ConsecNoshows # 1: 1 0 0 # 2: 1 1 1 # 3: 1 0 0 # 4: 1 1 1 # 5: 1 1 2 # 6: 1 1 3 # 7: 2 0 0 # 8: 2 0 0 # 9: 2 1 1 # 10: 2 1 2 # 11: 2 0 0 # 12: 2 1 1

Esto es básicamente grupos por PatientID y "run-length-encoding" de Noshow y crea secuencias usando los tamaños de grupo mientras se multiplica por Noshow para mantener solo los valores cuando Noshow == 1