2010-07-21 11 views
59

Quiero dividir un marco de datos en varios más pequeños. Esto parece una pregunta muy trivial, sin embargo, no puedo encontrar una solución desde la búsqueda web.¿Cómo dividir un marco de datos?

+1

nunca entendió 'split()', pero utilizando [ 'ntile' de' dplyr'] (http://stackoverflow.com/a/27646599/1888983) y luego filtrado por el índice de grupo ("cuartil") hicieron lo que quería: 'group = df [df $ cuartil == i,]'. – jozxyqk

Respuesta

18

Si desea dividir un marco de datos de acuerdo con los valores de alguna variable, sugiero usar daply() del paquete plyr.

library(plyr) 
x <- daply(df, .(splitting_variable), function(x)return(x)) 

Ahora, x es una matriz de tramas de datos. Para acceder a uno de los marcos de datos, puede indexarlo con el nombre del nivel de la variable de división.

x$Level1 
#or 
x[["Level1"]] 

estaría seguro de que no hay otras maneras más inteligentes para hacer frente a los datos antes de dividirlo en varias tramas de datos sin embargo.

+0

indique por adelantado el paquete del que proviene una función no básica - ¿presumiblemente quiere decir daply del paquete plyr? – mdsumner

+0

he cargado en mi plyr fragmento de código, así que pensé que era clara, pero voy a editar la prosa respuesta para mayor claridad. – JoFrhwld

+1

¿No quieres decir 'dlply'? – hadley

51

También puede cortar la trama de datos en un número arbitrario de tramas de datos más pequeños. Aquí, cortamos en dos marcos de datos.

x = data.frame(num = 1:26, let = letters, LET = LETTERS) 
set.seed(10) 
split(x, sample(rep(1:2, 13))) 

da

$`1` 
    num let LET 
3 3 c C 
6 6 f F 
10 10 j J 
12 12 l L 
14 14 n N 
15 15 o O 
17 17 q Q 
18 18 r R 
20 20 t T 
21 21 u U 
22 22 v V 
23 23 w W 
26 26 z Z 

$`2` 
    num let LET 
1 1 a A 
2 2 b B 
4 4 d D 
5 5 e E 
7 7 g G 
8 8 h H 
9 9 i I 
11 11 k K 
13 13 m M 
16 16 p P 
19 19 s S 
24 24 x X 
25 25 y Y 
+0

Greg, Su solución funciona! gracias. – Leo5188

+0

No hay problema. Me alegra que lo haya hecho – Greg

+1

Hey greg, no pude entender la sintaxis del comando de muestra, ¿puedes explicarlo? – Anirudh

3

La respuesta que desea depende en gran medida de cómo y por qué quiere romper la trama de datos.

Por ejemplo, si quiere omitir algunas variables, puede crear nuevos marcos de datos a partir de columnas específicas de la base de datos. Los subíndices entre paréntesis después del marco de datos se refieren a los números de filas y columnas. Echa un vistazo a Spoetry para una descripción completa.

newdf <- mydf[,1:3] 

O bien, puede elegir filas específicas.

newdf <- mydf[1:3,] 

Y estos subíndices también pueden ser pruebas lógicas, tales como la elección de las filas que contienen un valor en particular, o factores con un valor deseado.

¿Qué quieres hacer con los trozos sobrantes? ¿Necesita realizar la misma operación en cada porción de la base de datos? Luego, querrá asegurarse de que los subconjuntos del marco de datos terminen en un objeto conveniente, como una lista, que lo ayudará a realizar el mismo comando en cada fragmento del marco de datos.

12

Me acaba de publicar una especie de un RFC que podría ayudarle a: Split a vector into chunks in R

x = data.frame(num = 1:26, let = letters, LET = LETTERS) 
## number of chunks 
n <- 2 
dfchunk <- split(x, factor(sort(rank(row.names(x))%%n))) 
dfchunk 
$`0` 
    num let LET 
1 1 a A 
2 2 b B 
3 3 c C 
4 4 d D 
5 5 e E 
6 6 f F 
7 7 g G 
8 8 h H 
9 9 i I 
10 10 j J 
11 11 k K 
12 12 l L 
13 13 m M 

$`1` 
    num let LET 
14 14 n N 
15 15 o O 
16 16 p P 
17 17 q Q 
18 18 r R 
19 19 s S 
20 20 t T 
21 21 u U 
22 22 v V 
23 23 w W 
24 24 x X 
25 25 y Y 
26 26 z Z 

Cheers, Sebastián

10

También es posible usar

data2 <- data[data$sum_points == 2500, ] 

Esto hará que una trama de datos con los valores donde sum_points = 2500

Da:

airfoils sum_points field_points init_t contour_t field_t 
... 
491  5  2500   5625 0.000086 0.004272 6.321774 
498  5  2500   5625 0.000087 0.004507 6.325083 
504  5  2500   5625 0.000088 0.004370 6.336034 
603  5  250  10000 0.000072 0.000525 1.111278 
577  5  250  10000 0.000104 0.000559 1.111431 
587  5  250  10000 0.000072 0.000528 1.111524 
606  5  250  10000 0.000079 0.000538 1.111685 
.... 
> data2 <- data[data$sum_points == 2500, ] 
> data2 
airfoils sum_points field_points init_t contour_t field_t 
108  5  2500   625 0.000082 0.004329 0.733109 
106  5  2500   625 0.000102 0.004564 0.733243 
117  5  2500   625 0.000087 0.004321 0.733274 
112  5  2500   625 0.000081 0.004428 0.733587 
+0

hola, ¿cómo usted va sobre si desea dividir de forma dinámica en un data_frame diferente en función de valores únicos de esa columna.? –

3

Si desea dividir por valores en una de las columnas, se puede utilizar lapply. Por ejemplo, para dividir ChickWeight en un conjunto de datos independiente para cada polluelo:

data(ChickWeight) 
lapply(unique(ChickWeight$Chick), function(x) ChickWeight[ChickWeight$Chick == x,]) 
1

Splitting la trama de datos parece contraproducente. En lugar de ello, utilizar la fracción de aplicar-combinar paradigma, por ejemplo, generar algunos datos

df = data.frame(grp=sample(letters, 100, TRUE), x=rnorm(100)) 

divide entonces sólo las columnas relevantes y aplicar la función de scale() a x en cada grupo, y combinar los resultados (usando split<- o ave)

df$z = 0 
split(df$z, df$grp) = lapply(split(df$x, df$grp), scale) 
## alternative: df$z = ave(df$x, df$grp, FUN=scale) 

Esto será muy rápido en comparación con data.frames de división, y el resultado sigue siendo usable en el análisis aguas abajo sin iteración. Creo que la sintaxis es dplyr

library(dplyr) 
df %>% group_by(grp) %>% mutate(z=scale(x)) 

En general esta solución dplyr es más rápido que la división de tramas de datos, pero no tan rápido como una fracción de aplicar-se combinan.

Cuestiones relacionadas