2016-05-19 2 views
4

Suggestions pour obtenir un transfert fluide de foo à foo2 (de préférence avec les paquets tidyr ou reshape2)?Des données longues à des données multiples avec plusieurs colonnes

C'est un peu comme this question, mais pas exactement, je pense, parce que je ne veux pas d'auto-nombre de colonnes, il suffit d'élargir plusieurs colonnes. C'est aussi un peu comme this question, mais encore une fois, je ne pense pas que je veux que les colonnes varient avec une valeur de ligne comme dans cette réponse. Ou, une réponse valide à cette question est de me convaincre que c'est exactement comme l'un des autres. La solution dans la deuxième question de "deux décasts plus une fusion" est la plus attrayante en ce moment, car elle est compréhensible pour moi.

foo:

foo = data.frame(group=c('a', 'a', 'b', 'b', 'c', 'c'), 
        times=c('before', 'after', 'before', 'after', 'before', 'after'), 
        action_rate=c(0.1,0.15, 0.2, 0.18,0.3, 0.35), 
        num_users=c(100, 100, 200, 200, 300, 300)) 
foo <- transform(foo, 
       action_rate_c95 = 1.95 * sqrt(action_rate*(1-action_rate)/num_users)) 

> foo 
    group times action_rate num_users action_rate_c95 
1  a before  0.10  100  0.05850000 
2  a after  0.15  100  0.06962893 
3  b before  0.20  200  0.05515433 
4  b after  0.18  200  0.05297400 
5  c before  0.30  300  0.05159215 
6  c after  0.35  300  0.05369881 

foo2:

foo2 <- data.frame(group=c('a', 'b', 'c'), 
        action_rate_before=c(0.1,0.2, 0.3), 
        action_rate_after=c(0.15, 0.18,0.35), 
        action_rate_c95_before=c(0.0585,0.055, 0.05159), 
        action_rate_c95_after=c(0.069, 0.0530,0.0537), 
        num_users=c(100, 200, 300)) 

> foo2 
    group action_rate_before action_rate_after action_rate_c95_before 
1  a    0.1    0.15     0.0585 
2  b    0.2    0.18     0.0550 
3  c    0.3    0.35     0.05159 
    action_rate_c95_after num_users 
1     0.0690  100 
2     0.0530  200 
3     0.0537  300 

Répondre

5

Voici une autre alternative utilisant tidyr:

library(tidyr) 
foo %>% 
    gather(key, value, -group, -times, -num_users) %>% 
    unite(col, key, times) %>% 
    spread(col, value) 

Ce qui donne:

# group num_users action_rate_after action_rate_before action_rate_c95_after 
#1  a  100    0.15    0.1   0.06962893 
#2  b  200    0.18    0.2   0.05297400 
#3  c  300    0.35    0.3   0.05369881 
# action_rate_c95_before 
#1    0.05850000 
#2    0.05515433 
#3    0.05159215 
7

Vous pouvez utiliser data.table au lieu de reshape2, parce que sa fonction dcast() accepte plusieurs variables, et est plus rapide aussi:

require(data.table) 
setDT(foo) 
dcast(foo,group+num_users~times,value.var=c("action_rate","action_rate_c95")) 

    group num_users action_rate_after action_rate_before action_rate_c95_after action_rate_c95_before 
1:  a  100    0.15    0.1   0.06962893    0.05850000 
2:  b  200    0.18    0.2   0.05297400    0.05515433 
3:  c  300    0.35    0.3   0.05369881    0.05159215 
+1

Si vous ne voulez pas la répétition '' num_users_before' et num_users_after' vous pouvez juste faire 'dcast (toto, groupe + num_users ~ times, valeur.var = c (" action_rate "," action_rate_c95 "))'. Je pense que cela vous donnerait exactement la sortie attendue des OP. –

+0

Bonne idée @MikeyMike! – HubertL

4

Voici une option base R avec reshape

reshape(foo, idvar=c("group", "num_users"), timevar="times", direction="wide") 
# group num_users action_rate.before action_rate_c95.before action_rate.after 
#1  a  100    0.1    0.05850000    0.15 
#3  b  200    0.2    0.05515433    0.18 
#5  c  300    0.3    0.05159215    0.35 
# action_rate_c95.after 
#1   0.06962893 
#3   0.05297400 
#5   0.05369881