tutorial sheet formatstyle extension dtoptions data cheat r data.table

sheet - render dt r



usando data.table para marcar el primer registro(o el Ășltimo) en un grupo (3)

Dada una clave de clasificación, ¿hay un acceso directo data.table para duplicar la first y la last funcionalidad encontrada en SAS y SPSS?

El acercamiento peatonal debajo de las banderas marca el primer registro de un grupo.

Dada la elegancia de data.table (con la que me estoy familiarizando poco a poco), asumo que hay un atajo con una combinación automática, pero todavía estoy intentando resolverlo.

Aquí está el ejemplo:

require(data.table) set.seed(123) n <- 17 DT <- data.table(x=sample(letters[1:3],n,replace=T), y=sample(LETTERS[1:3],n,replace=T)) sortkey <- c("x","y") setkeyv(DT,sortkey) key <- paste(DT$x,DT$y,sep="-") nw <- c( T , key[2:n]!=key[1:(n-1)] ) DT$first <- 1*nw DT


Aquí hay un par de soluciones usando data.table :

## Option 1 (cleaner solution, added 2016-11-29) uDT <- unique(DT) DT[, c("first","last"):=0L] DT[uDT, first:=1L, mult="first"] DT[uDT, last:=1L, mult="last"] ## Option 2 (original answer, retained for posterity) DT <- cbind(DT, first=0L, last=0L) DT[DT[unique(DT),,mult="first", which=TRUE], first:=1L] DT[DT[unique(DT),,mult="last", which=TRUE], last:=1L] head(DT) # x y first last # [1,] a A 1 1 # [2,] a B 1 1 # [3,] a C 1 0 # [4,] a C 0 1 # [5,] b A 1 1 # [6,] b B 1 1

Obviamente hay mucho contenido en cada una de esas líneas. La construcción clave, sin embargo, es la siguiente, que devuelve el índice de fila del primer registro en cada grupo:

DT[unique(DT),,mult="first", which=TRUE] # [1] 1 2 3 5 6 7 11 13 15


Una forma fácil es usar la función duplicated() . Cuando se aplica a un marco de datos, produce un vector donde una entrada es VERDADERA si y solo si la combinación del valor de la fila no ha ocurrido antes, al bajar el marco de datos.

DT$first <- !duplicated( DT[, list(x,y) ]) DT$last <- rev(!duplicated( DT[, list(rev(x),rev(y)) ])) > DT x y first last [1,] a A TRUE TRUE [2,] a B TRUE TRUE [3,] a C TRUE FALSE [4,] a C FALSE TRUE [5,] b A TRUE TRUE [6,] b B TRUE TRUE [7,] b C TRUE FALSE [8,] b C FALSE FALSE [9,] b C FALSE FALSE [10,] b C FALSE TRUE [11,] c A TRUE FALSE [12,] c A FALSE TRUE [13,] c B TRUE FALSE [14,] c B FALSE TRUE [15,] c C TRUE FALSE [16,] c C FALSE FALSE [17,] c C FALSE TRUE

Otra forma sin usar duplicated() es:

DT[ unique(DT), list(first = c(1, rep(0,length(y)-1)), last = c(rep(0,length(y)-1),1 )) ] x y first last [1,] a A 1 1 [2,] a B 1 1 [3,] a C 1 0 [4,] a C 0 1 [5,] b A 1 1 [6,] b B 1 1 [7,] b C 1 0 [8,] b C 0 0 [9,] b C 0 0 [10,] b C 0 1 [11,] c A 1 0 [12,] c A 0 1 [13,] c B 1 0 [14,] c B 0 1 [15,] c C 1 0 [16,] c C 0 0 [17,] c C 0 1


Una forma más sencilla de lo que Josh puede ser.

unique(DT) unique(DT,fromLast=TRUE]