Pregunta
Utilizando dplyr, ¿cómo selecciono las observaciones / filas superiores e inferiores de datos agrupados en una declaración?
Datos y ejemplo
Dado un marco de datos
df <- data.frame(id=c(1,1,1,2,2,2,3,3,3),
stopId=c("a","b","c","a","b","c","a","b","c"),
stopSequence=c(1,2,3,3,1,4,3,1,2))
Puedo obtener las observaciones superior e inferior de cada grupo usando slice, pero usando dos declaraciones separadas:
firstStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(1) %>%
ungroup
lastStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(n()) %>%
ungroup
¿Puedo combinar estos dos statmenets en uno que seleccione las observaciones superiores e inferiores?

Respuestas:
Probablemente hay una forma más rápida:
fuente
rownumber() %in% c(1, n())evitaría la necesidad de ejecutar el escaneo vectorial dos veces_? es decirfilter(row_number() %in% c(1, n()))Solo para completar: puede pasar
sliceun vector de índices:lo que da
fuente
filter- no he probado esto, pero mira aquímtcars[1, ] %>% slice(c(1, n()))en ese sentido, la elección entre ellos depende de lo que desea que se devuelva. Esperaría que los tiempos sean cercanos a menos quensea muy grande (donde se podría favorecer el corte), pero tampoco lo he probado.No
dplyr, pero es mucho más directo usandodata.table:Explicación más detallada:
Asegúrese de revisar la Getting Started wiki para conseguir los
data.tablefundamentos cubiertosfuente
df[ df[order(stopSequence), .I[c(1,.N)], keyby=id]$V1 ]. Veridaparecer dos veces es extraño para mí.setDTllamada. Entonces unaorderllamada no es necesaria aquí.df[order(stopSequence), .SD[c(1L,.N)], by = id]. Ver aquíid. Creo quedf[order(stopSequence), .SD[c(1L, .N)], keyby = id]debe hacer el truco (con la diferencia menor a la solución anterior que el resultado serákeyedAlgo como:
Con
dousted puede realizar cualquier cantidad de operaciones en el grupo, pero la respuesta de @ jeremycg es mucho más apropiada para esta tarea.fuente
slice, comodf %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n()))doejemplo aquí podría ayudar a otros cuandosliceno funcionen (es decir, operaciones más complejas en un grupo). Y, debe publicar su comentario como respuesta (es el mejor).Sé la pregunta especificada
dplyr. Pero, dado que otros ya publicaron soluciones con otros paquetes, decidí probar también con otros paquetes:Paquete base:
tabla de datos:
sqldf:
En una consulta:
Salida:
fuente
usando
which.minywhich.max:punto de referencia
También es mucho más rápido que la respuesta actual aceptada porque encontramos el valor mínimo y máximo por grupo, en lugar de ordenar toda la columna stopSequence.
fuente
Utilizando
data.table:fuente
Otro enfoque con lapply y una declaración dplyr. Podemos aplicar un número arbitrario de cualquier función de resumen a la misma declaración:
Por ejemplo, podría estar interesado en filas con el valor max stopSequence y hacer:
fuente
Una alternativa diferente base de R sería primero
orderporidystopSequence,splitellos basados enidy para cadaidseleccionamos sólo el primero y el último índice y el subconjunto de la trama de datos usando esos índices.O similar usando
byfuente