2010-07-21 3 views
59

Je souhaite diviser une trame de données en plusieurs plus petites. Cela ressemble à une question très triviale, mais je ne trouve pas de solution de recherche sur le Web.Comment diviser une trame de données?

+1

jamais compris 'split()', mais en utilisant [ '' ntile' de dplyr'] (http://stackoverflow.com/a/27646599/1888983), puis en filtrant par l'indice du groupe ("quartile") a fait ce que je voulais: 'group = df [df $ quartile == i,]'. – jozxyqk

Répondre

18

Si vous souhaitez diviser une base de données en fonction des valeurs d'une variable, je suggère d'utiliser daply() à partir du package plyr.

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

Maintenant, x est un tableau de dataframes. Pour accéder à l'une des données, vous pouvez l'indexer avec le nom du niveau de la variable de fractionnement.

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

je serais sûr qu'il n'y a pas d'autres moyens plus intelligents pour traiter vos données avant de la découper en plusieurs dataframes bien.

+0

Veuillez indiquer d'avance le paquet d'où provient une fonction non-base - vous voulez probablement dire daply de paquet plyr? Je – mdsumner

+0

chargé plyr dans mon extrait de code, donc je pensais qu'il était clair, mais je vais modifier la prose de réponse pour plus de clarté. – JoFrhwld

+1

Ne voulez-vous pas dire «dlply»? – hadley

51

Vous pouvez également couper la trame de données en un nombre arbitraire de dataframes plus petites. Ici, nous coupons en deux dataframes.

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

donne

$`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, Votre solution fonctionne! merci. – Leo5188

+0

Pas de problème. Je suis content que ça l'ait fait. – Greg

+1

Hey greg, je ne pouvais pas comprendre la syntaxe de l'exemple de commande, pouvez-vous l'expliquer. – Anirudh

3

La réponse que vous voulez dépend beaucoup de comment et pourquoi vous voulez briser la trame de données. Par exemple, si vous souhaitez omettre certaines variables, vous pouvez créer de nouvelles trames de données à partir de colonnes spécifiques de la base de données. Les indices entre parenthèses après la trame de données renvoient aux numéros de lignes et de colonnes. Découvrez Spoetry pour une description complète.

newdf <- mydf[,1:3] 

Vous pouvez également choisir des lignes spécifiques.

newdf <- mydf[1:3,] 

Et ces indices peuvent également être des tests logiques, comme le choix de lignes qui contiennent une valeur particulière, ou les facteurs ayant une valeur souhaitée.

Que voulez-vous faire avec les morceaux restants? Avez-vous besoin d'effectuer la même opération sur chaque segment de la base de données? Ensuite, vous voudrez vous assurer que les sous-ensembles de la trame de données se retrouvent dans un objet pratique, comme une liste, qui vous aidera à exécuter la même commande sur chaque segment de la trame de données.

12

Je viens de publier une sorte de RFC qui pourraient vous aider: 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, Sebastian

10

Vous pouvez également utiliser

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

Cela fera une trame de données avec où les valeurs sum_points = 2500

Il donne:

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

Salut, comment feriez-vous si vous vouliez diviser dynamiquement dans un autre data_frame fondé sur des valeurs uniques dans cette colonne.? –

3

Si vous voulez diviser par des valeurs dans l'une des colonnes, vous pouvez utiliser lapply. Par exemple, pour diviser ChickWeight dans un jeu de données pour chaque poussin:

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

Fractionnement la trame de données semble contre-productif. Au lieu de cela, utilisez le paradigme split-apply-combiner, par exemple, générer des données

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

puis diviser uniquement les colonnes correspondantes et d'appliquer la fonction scale() à x dans chaque groupe, et combiner les résultats (en utilisant split<- ou 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) 

Ce sera très rapide par rapport à data.frames de division, et le résultat reste utilisable dans l'analyse en aval sans itération. Je pense que la syntaxe dplyr est

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

En général, cette solution dplyr est plus rapide que le fractionnement des trames de données, mais pas aussi vite que split-apply-combiner.

Questions connexes