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
slice
un 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 quen
sea 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.table
fundamentos cubiertosfuente
df[ df[order(stopSequence), .I[c(1,.N)], keyby=id]$V1 ]
. Verid
aparecer dos veces es extraño para mí.setDT
llamada. Entonces unaorder
llamada 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ákey
edAlgo como:
Con
do
usted 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()))
do
ejemplo aquí podría ayudar a otros cuandoslice
no 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.min
ywhich.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
order
porid
ystopSequence
,split
ellos basados enid
y para cadaid
seleccionamos sólo el primero y el último índice y el subconjunto de la trama de datos usando esos índices.O similar usando
by
fuente