Muestra filas aleatorias dentro de cada grupo en un data.table

¿Cómo usará data.table para tomar eficientemente una muestra de filas dentro de cada grupo en un dataframe?

DT = data.table(a = sample(1:2), b = sample(1:1000,20)) DT ab 1: 2 562 2: 1 183 3: 2 180 4: 1 874 5: 2 533 6: 1 21 7: 2 57 8: 1 20 9: 2 39 10: 1 948 11: 2 799 12: 1 893 13: 2 993 14: 1 69 15: 2 906 16: 1 347 17: 2 969 18: 1 130 19: 2 118 20: 1 732 

Estaba pensando en algo como: DT[ , sample(??, 3), by = a] que devolvería una muestra de tres filas para cada “a” (el orden de las filas devueltas no es significativo):

  ab 1: 2 180 2: 2 57 3: 2 799 4: 1 69 5: 1 347 6: 1 732 

Tal vez algo como esto?

 > DT[,.SD[sample(.N, min(3,.N))],by = a] ab 1: 1 744 2: 1 497 3: 1 167 4: 2 888 5: 2 950 6: 2 343 

(Gracias a Josh por la corrección, a continuación).

Creo que la respuesta de Joran puede generalizarse aún más. Los detalles están aquí ( ¿Cómo se muestrean los grupos en una tabla de datos con una advertencia? ), Pero creo que esta solución da cuenta de los casos en los que no hay “3” filas para tomar muestras.

La solución actual producirá un error al intentar muestrear “x” veces desde filas que tienen menos de “x” valores comunes. En el caso siguiente, x = 3. Y toma en consideración esta advertencia. (Solución hecha por nrussell)

 set.seed(123) ## DT <- data.table( a=c(1,1,1,1:15,1,1), b=sample(1:1000,20)) ## R> DT[,.SD[sample(.N,min(.N,3))],by = a] ab 1: 1 288 2: 1 881 3: 1 409 4: 2 937 5: 3 46 6: 4 525 7: 5 887 8: 6 548 9: 7 453 10: 8 948 11: 9 449 12: 10 670 13: 11 566 14: 12 102 15: 13 993 16: 14 243 17: 15 42 

Inspirado por esta respuesta de David Arenburg , otro método para evitar la asignación de .SD sería muestrear los grupos, luego volver a unir los datos originales usando .EACHI

 DT[ DT[, sample(.N, 3), by=a], b[i.V1], on="a", by=.EACHI] # a V1 # 1: 2 42 # 2: 2 498 # 3: 2 179 # 4: 1 469 # 5: 1 93 # 6: 1 898 

donde la línea DT[, sample(.N, 3), by=a] nos da una muestra para cada grupo

 # a V1 # 1: 1 9 # 2: 1 3 # 3: 1 2 # 4: 2 4 # 5: 2 9 # --- 

entonces podemos usar V1 para darnos el b correspondiente.

Muestreo estratificado > sobremuestreo

 size=don[y==1,.(strata=length(iden)),by=.(y,x)] # count of iden by strata table(don$x,don$y) don<-merge(don,size[,.(y,strata)],by="x") #merge strata values don_strata=don[,.SD[sample(.N,strata)],by=.(y,x)]