Tengo un marco de datos con 10 columnas, que recopilan acciones de "usuarios", donde una de las columnas contiene un ID (no único, que identifica al usuario) (columna 10). la longitud del marco de datos es de aproximadamente 750000 filas. Estoy tratando de extraer marcos de datos individuales (obteniendo una lista o vector de marcos de datos) divididos por la columna que contiene el identificador de "usuario", para aislar las acciones de un solo actor.
ID | Data1 | Data2 | ... | UserID
1 | aaa | bbb | ... | u_001
2 | aab | bb2 | ... | u_001
3 | aac | bb3 | ... | u_001
4 | aad | bb4 | ... | u_002
resultando en
list(
ID | Data1 | Data2 | ... | UserID
1 | aaa | bbb | ... | u_001
2 | aab | bb2 | ... | u_001
3 | aac | bb3 | ... | u_001
,
4 | aad | bb4 | ... | u_002
...)
Lo siguiente funciona muy bien para mí en una pequeña muestra (1000 filas):
paths = by(smallsampleMat, smallsampleMat[,"userID"], function(x) x)
y luego acceder al elemento que quiero por rutas [1] por ejemplo.
Cuando se aplica en el marco de datos grande original o incluso en una representación matricial, esto ahoga mi máquina (4GB RAM, MacOSX 10.6, R 2.15) y nunca se completa (sé que existe una versión R más nueva, pero creo que este no es el problema principal ).
Parece que la división es más eficaz y después de mucho tiempo se completa, pero no sé (conocimiento inferior de R) cómo dividir la lista resultante de vectores en un vector de matrices.
path = split(smallsampleMat, smallsampleMat[,10])
También he considerado usar big.matrix
etc., pero sin mucho éxito, eso aceleraría el proceso.
dlply(df, .(userid))
y descubrí que es malo en comparación consplit
incluso sin involucrar el tiempo de ejecución derequire(plyr)
, ¡gracias y OP!Desde la versión 0.8.0,
dplyr
ofrece una práctica función llamadagroup_split()
:# On sample data from @Aus_10 df %>% group_split(g) [[1]] # A tibble: 25 x 3 ran_data1 ran_data2 g <dbl> <dbl> <fct> 1 2.04 0.627 A 2 0.530 -0.703 A 3 -0.475 0.541 A 4 1.20 -0.565 A 5 -0.380 -0.126 A 6 1.25 -1.69 A 7 -0.153 -1.02 A 8 1.52 -0.520 A 9 0.905 -0.976 A 10 0.517 -0.535 A # … with 15 more rows [[2]] # A tibble: 25 x 3 ran_data1 ran_data2 g <dbl> <dbl> <fct> 1 1.61 0.858 B 2 1.05 -1.25 B 3 -0.440 -0.506 B 4 -1.17 1.81 B 5 1.47 -1.60 B 6 -0.682 -0.726 B 7 -2.21 0.282 B 8 -0.499 0.591 B 9 0.711 -1.21 B 10 0.705 0.960 B # … with 15 more rows
Para no incluir la columna de agrupación:
df %>% group_split(g, keep = FALSE)
fuente
Me encontré con esta respuesta y en realidad quería AMBOS grupos (datos que contienen ese usuario y datos que contienen todo menos ese usuario). No es necesario para los detalles de esta publicación, pero pensé que lo agregaría en caso de que alguien estuviera buscando en Google el mismo problema que yo.
df <- data.frame( ran_data1=rnorm(125), ran_data2=rnorm(125), g=rep(factor(LETTERS[1:5]), 25) ) test_x = split(df,df$g)[['A']] test_y = split(df,df$g!='A')[['TRUE']]
Así es como se ve:
head(test_x) x y g 1 1.1362198 1.2969541 A 6 0.5510307 -0.2512449 A 11 0.0321679 0.2358821 A 16 0.4734277 -1.2889081 A 21 -1.2686151 0.2524744 A > head(test_y) x y g 2 -2.23477293 1.1514810 B 3 -0.46958938 -1.7434205 C 4 0.07365603 0.1111419 D 5 -1.08758355 0.4727281 E 7 0.28448637 -1.5124336 B 8 1.24117504 0.4928257 C
fuente