¿Cómo extraer las primeras n filas por grupo?

Tengo un data.table dt . Esta data.table está ordenada primero por date columna (mi variable de agrupamiento), luego por columna age :

 library(data.table) setkeyv(dt, c("date", "age")) # Sorts table first by column "date" then by "age" > dt date age name 1: 2000-01-01 3 Andrew 2: 2000-01-01 4 Ben 3: 2000-01-01 5 Charlie 4: 2000-01-02 6 Adam 5: 2000-01-02 7 Bob 6: 2000-01-02 8 Campbell 

Mi pregunta es: me pregunto si es posible extraer las primeras 2 filas para cada fecha única. O redactado de manera más general:

¿Cómo extraer las primeras n filas dentro de cada grupo ?

En este ejemplo, el resultado en dt.f sería:

 > dt.f = ???????? # function of dt to extract the first 2 rows per unique date > dt.f date age name 1: 2000-01-01 3 Andrew 2: 2000-01-01 4 Ben 3: 2000-01-02 6 Adam 4: 2000-01-02 7 Bob 

ps Aquí está el código para crear la data.table anteriormente mencionada:

 install.packages("data.table") library(data.table) date <- c("2000-01-01","2000-01-01","2000-01-01", "2000-01-02","2000-01-02","2000-01-02") age <- c(3,4,5,6,7,8) name <- c("Andrew","Ben","Charlie","Adam","Bob","Campbell") dt <- data.table(date, age, name) setkeyv(dt,c("date","age")) # Sorts table first by column "date" then by "age" 

Sí, simplemente use .SD e indexe según sea necesario.

  DT[, .SD[1:2], by=date] date age name 1: 2000-01-01 3 Andrew 2: 2000-01-01 4 Ben 3: 2000-01-02 6 Adam 4: 2000-01-02 7 Bob 

Editado según la sugerencia de @ eddi.

La sugerencia de @ eddi es acertada:

Use esto en cambio, por velocidad:

  DT[DT[, .I[1:2], by = date]$V1] # using a slightly larger data set > microbenchmark(SDstyle=DT[, .SD[1:2], by=date], IStyle=DT[DT[, .I[1:2], by = date]$V1], times=200L) Unit: milliseconds expr min lq median uq max neval SDstyle 13.567070 16.224797 22.170302 24.239881 88.26719 200 IStyle 1.675185 2.018773 2.168818 2.269292 11.31072 200 

Probablemente no sea el método más rápido, pero proporciona cierta flexibilidad si no utiliza variables con clave y necesita más flexibilidad. Al cambiar el Row.ID seleccionado, la cantidad de primeros objetos se puede ajustar según sea necesario.

 dt[, .( age , name , Row.ID = rank(age) ) , by = list(date)][Row.ID %in% (1:2), .(date , age , name )]