una tabla saca resueltos rango para numero marca intervalos frecuencias frecuencia estadistica ejercicios ejemplos distribucion definicion datos como clase calcular agrupados r dplyr

tabla - Seleccione la primera y la última fila de los datos agrupados



numero de intervalos definicion (8)

Algo como:

library(dplyr) 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)) first_last <- function(x) { bind_rows(slice(x, 1), slice(x, n())) } df %>% group_by(id) %>% arrange(stopSequence) %>% do(first_last(.)) %>% ungroup ## Source: local data frame [6 x 3] ## ## id stopId stopSequence ## 1 1 a 1 ## 2 1 c 3 ## 3 2 b 1 ## 4 2 c 4 ## 5 3 b 1 ## 6 3 a 3

Con do puedes realizar cualquier cantidad de operaciones en el grupo, pero la respuesta de @ jeremycg es mucho más apropiada para esta tarea.

Pregunta

Usando 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 una división, 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?


No es dplyr , pero es mucho más directo usando data.table :

library(data.table) setDT(df) df[ df[order(id, stopSequence), .I[c(1L,.N)], by=id]$V1 ] # id stopId stopSequence # 1: 1 a 1 # 2: 1 c 3 # 3: 2 b 1 # 4: 2 c 4 # 5: 3 b 1 # 6: 3 a 3

Explicación más detallada:

# 1) get row numbers of first/last observations from each group # * basically, we sort the table by id/stopSequence, then, # grouping by id, name the row numbers of the first/last # observations for each id; since this operation produces # a data.table # * .I is data.table shorthand for the row number # * here, to be maximally explicit, I''ve named the variable V1 # as row_num to give other readers of my code a clearer # understanding of what operation is producing what variable first_last = df[order(id, stopSequence), .(row_num = .I[c(1L,.N)]), by=id] idx = first_last$row_num # 2) extract rows by number df[idx]

Asegúrese de consultar el wiki de introducción para obtener los data.table básicos de la data.table cubiertos.


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:

lapply(c(first, last), function(x) df %>% group_by(id) %>% summarize_all(funs(x))) %>% bind_rows()

Por ejemplo, también podría estar interesado en filas con el valor max stopSequence y hacer:

lapply(c(first, last, max("stopSequence")), function(x) df %>% group_by(id) %>% summarize_all(funs(x))) %>% bind_rows()


Probablemente haya una forma más rápida:

df %>% group_by(id) %>% arrange(stopSequence) %>% filter(row_number()==1 | row_number()==n())


Sé que la pregunta especificada dplyr . Pero, dado que otros ya publicaron soluciones usando otros paquetes, decidí probar también usar otros paquetes:

Paquete base:

df <- df[with(df, order(id, stopSequence, stopId)), ] merge(df[!duplicated(df$id), ], df[!duplicated(df$id, fromLast = TRUE), ], all = TRUE)

tabla de datos:

df <- setDT(df) df[order(id, stopSequence)][, .SD[c(1,.N)], by=id]

sqldf:

library(sqldf) min <- sqldf("SELECT id, stopId, min(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId") max <- sqldf("SELECT id, stopId, max(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId") sqldf("SELECT * FROM min UNION SELECT * FROM max")

En una consulta:

sqldf("SELECT * FROM (SELECT id, stopId, min(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId) UNION SELECT * FROM (SELECT id, stopId, max(stopSequence) AS StopSequence FROM df GROUP BY id ORDER BY id, StopSequence, stopId)")

Salida:

id stopId StopSequence 1 1 a 1 2 1 c 3 3 2 b 1 4 2 c 4 5 3 a 3 6 3 b 1


Solo para completar: puede pasar el slice un vector de índices:

df %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n()))

lo que da

id stopId stopSequence 1 1 a 1 2 1 c 3 3 2 b 1 4 2 c 4 5 3 b 1 6 3 a 3


Una alternativa base R diferente sería order primero por id y stopSequence , split en función del id y para cada id seleccionamos solo el primer y el último índice y subconjunto el marco de datos usando esos índices.

df[sapply(with(df, split(order(id, stopSequence), id)), function(x) c(x[1], x[length(x)])), ] # id stopId stopSequence #1 1 a 1 #3 1 c 3 #5 2 b 1 #6 2 c 4 #8 3 b 1 #7 3 a 3

O similar usando by

df[unlist(with(df, by(order(id, stopSequence), id, function(x) c(x[1], x[length(x)])))), ]


Usando data.table :

# convert to data.table setDT(df) # order, group, filter df[order(stopSequence)][, .SD[c(1, .N)], by = id] id stopId stopSequence 1: 1 a 1 2: 1 c 3 3: 2 b 1 4: 2 c 4 5: 3 b 1 6: 3 a 3