2010-10-07 46 views
3

J'ai une question sur ddply et sous-ensemble.Classer ou couper les données par liste de classes et résumer avec ddply

Je dataframe df comme ceci:

df <- read.table(textConnection(
" id v_idn v_seed v_time v_pop v_rank v_perco 
    1 15 125648 0  150 1  15  
    2 17 125648 0  120 2  5  
    3 18 125648 0  100 3  6  
    4 52 125648 0  25 4  1  

    5 17 125648 10  220 1  5  
    6 15 125648 10  160 2  15  
    7 18 125648 10  110 3  6  
    8 52 125648 10  50 4  1  

    9 56 -11152 0  250 1  17  
    10 15 -11152 0  180 2  15  
    11 18 -11152 0  110 3  6  
    12 22 -11152 0  5  4  14  

    13 56 -11152 10  250 1  17  
    14 15 -11152 10  180 2  15  
    15 22 -11152 10  125 3  14  
    16 18 -11152 10  120 4  6 "), header=TRUE)  

PREMIÈRE ÉTAPE:

J'ai une liste d'intervalles égaux avec cut_interval comme ceci:

myinterval <- cut_interval(c(15,5,6,1,17,14), length=10) 

J'ai donc deux niveaux ici: [0,10) et (10,20]

ÉTAPE:

Je veux chaque groupe/classe définit par mes deux niveaux v_cut ... comme ceci:

id v_idn v_seed v_time v_pop v_rank v_perco v_cut 
1 15 125648 0  150 1  15  (10,20] 
2 17 125648 0  120 2  5  [0,10) 
3 18 125648 0  100 3  6  [0,10) 
4 52 125648 0  25 4  1  [0,10) 

5 17 125648 10  220 1  5  [0,10) 
6 15 125648 10  160 2  15  (10,20] 
7 18 125648 10  110 3  6  [0,10) 
8 52 125648 10  50 4  1  [0,10) 

9 56 -11152 0  250 1  17  (10,20] 
10 15 -11152 0  180 2  15  (10,20] 
11 18 -11152 0  110 3  6  [0,10) 
12 22 -11152 0  5  4  14  (10,20] 

13 56 -11152 10  250 1  17  (10,20] 
14 15 -11152 10  180 2  15  (10,20] 
15 22 -11152 10  125 3  14  (10,20] 
16 18 -11152 10  120 4  6  [0,10) 

ÉTAPE 3:

Je veux savoir la variabilité de v_rank pour l'axe x, et le temps pour l'axe y, pour chaque groupe v_cut, donc j'ai besoin de calculer min, mean, max, sd pour la valeur v_rank avec quelque chose comme

ddply(df, .(v_cut,v_time), summarize ,mean = mean(v_rank), min = min(v_rank), max = max(v_rank), sd = sd(v_rank)) 

* RÉSULTAT WANTED: *

id v_time MEAN.v_rank ... v_cut 
1 0  2.25   (10,20] 
2 0  2.42   [0,10) 
3 10  2.25   [0,10) 
4 10  2.42   (10,20] 

MON PROBLÈME

Je ne sais pas comment passer l'étape 1 -> étape 2:/

Et s'il est possible de grouper par v_cut comme mon exemple à l'étape 3?

Y a-t-il une possibilité de faire les mêmes choses avec l'option "sous-ensemble" de ddply?

Encore une fois, merci beaucoup pour votre aide géniale!

MISE À JOUR 1:

J'ai une réponse pour aller à l'étape 1 Etape 2:

df$v_cut <- cut_interval(df$v_perco,n=10) 

J'utilise plyr, mais il y a peut-être une meilleure réponse dans ce cas?

Répondez pour passer à l'étape 2 à l'étape 3?

MISE À JOUR 2:

Brandon Bertelsen me donner une bonne réponse à la fonte + cast, mais maintenant (à comprendre) je veux faire la même opération avec plyr et ddply ..avec un autre résultat:

id v_idn v_time MEAN.v_rank ... v_cut 
    1 15 0  2.25   (10,20] 
    2 15 10  2.45   (10,20] 
    2 17 0  1.52   [0,10) 
    2 17 10  2.42   [0,10) 
    etc. 

J'essaie quelque chose comme ceci:

r('sumData <- ddply(df, .(v_idn,v_time), summarize,min = min(v_rank),mean = mean(v_rank), max = max(v_rank), sd=sd(v_rank))') 

Mais je veux avoir v_cut dans mon sumData dataframe, comment puis-je faire avec ddply? Y at-il une option pour faire cela? Ou fusionner avec initial df et key = v_idn pour ajouter la colonne v_cut à sumData est la seule bonne réponse?

+1

Un peu de données de test de débit (head (df), 5) aiderait. –

+0

Pour la mise à jour 2: Je ne suis pas sûr comment vous avez calculé 2.25. Parce que dans votre table d'exemple où: v_idn = 15 & v_time = 0, nous avons v_rank n = 2, sum = 3 (1 + 2) donc la moyenne serait sum/n = 1.5. –

Répondre

2

Vous n'avez pas vraiment besoin plyr pour cela, vous pouvez utiliser reshape

## Pull what you need 
dfx <- df[c("v_seed", "v_time","v_rank","v_perco")] 
## Bring in your cuts 
dfx <- data.frame(dfx, ifelse(df$v_perco > 10,"(10,20]", "[0,10)"))) 
## Rename v_cut 
colnames(dfx)[ncol(dfx)] <- "v_cut"  
## Melt it.  
dfx <- melt(dfx, id=c("v_cut", "v_seed", "v_time")) 
## Cast it. 
dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, c(mean,min,max,sd)) 

si vous voulez que la moyenne, puis remplacez la dernière ligne avec:

dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, mean) 

de type "DFX" et vous verrez un cadre de données avec ce que vous avez demandé.

+0

Thx pour aider, j'essaie votre solution, mais j'ai un problème avec la ligne "cast", "bound" n'existe pas dans la base de données df. Avez-vous une bonne documentation pour cette fonction parce que? cast ou? fondre look cryptique: s – reyman64

+0

whoopsie, "bound" devrait être v_cut –

+0

Je ne suis pas sûr de ce que vous voulez de v_cut, les réductions fournies ne le brisent pas dans les bacs de 10, mais plutôt n = 10, signifie 10 cases. Je pense que ce que vous voulez, c'est cut_interval (x, length = 10). –

2

Vous êtes juste un problème avec la syntaxe est tout:

## Add your cut 
df.new <- data.frame(df, ifelse(df$v_perco > 10,"(10,20]", "[0,10)")) 
## Rename v_cut 
colnames(df.new)[ncol(df.new)] <- "v_cut" 

## Careful here read the note below 
df.new <- ddply(df.new, .(v_idn, v_time), function(x) unique(data.frame(
mean = mean(x$v_rank), 
v_cut = x$v_cut 
))) 

Autre possibilité:

ddply(df.new, .(v_idn, v_time), summarise, mean=mean(v_rank)) 

Avec "(v_idn, v_time)" vous dites ddply que pour chaque combinaison de v_idn et v_time, vous voulez qu'il calcule la moyenne de v_rank.