2015-04-01 67 views
8

我的數據是有序的觀測數據,我希望儘可能保持排序的同時進行操作。tidyr :: spread和dplyr中的隱式排序::總結

this question的答案,我把「B」放在數據框的「A」之前。所產生的寬數據按列「名稱」排序,即首先是「A」,然後是「B」。

df = data.frame(name=c("B","B","A","A"), 
       group=c("g1","g2","g1","g2"), 
       V1=c(10,40,20,30), 
       V2=c(6,3,1,7)) 

gather(df, Var, Val, V1:V2) %>% 
unite(VarG, Var, group) %>% 
spread(VarG, Val) 

    name V1_g1 V1_g2 V2_g1 V2_g2 
1 A 20 30  1  7 
2 B 10 40  6  3 

有沒有辦法保持原來的順序?像這樣:

name V1_g1 V1_g2 V2_g1 V2_g2 
1 B 10 40  6  3 
2 A 20 30  1  7 

04/02編輯:我剛剛發現dplyr::summarise排序以及。 arrange(name, df$name)仍然可以恢復訂單。但是,我想知道包的設計是否需要額外的排序?

df %>% 
    group_by(name) %>% 
    summarise(n()) %>% 

    name n() 
1 A 2 
2 B 2 
+0

有趣。這似乎是在擴散步驟中,即使「名稱」變量的因子水平也得到了改變...... – A5C1D2H2I1M1N2O1R2T1 2015-04-01 04:09:05

回答

7

可以按名稱基於原始數據幀的順序進行排序:

gather(df, Var, Val, V1:V2) %>% 
    unite(VarG, Var, group) %>% 
    spread(VarG, Val) %>% 
    arrange(order(match(name, df$name))) 

# name V1_g1 V1_g2 V2_g1 V2_g2 
# 1 B 10 40  6  3 
# 2 A 20 30  1  7 
+1

謝謝。 'arrange(match(name,df $ name)'也是可行的,但是如何處理多個分組級別,比如說「name」,「name1」,「name2」,「spread」包含排序對我來說沒有任何意義默認情況下 – Dong 2015-04-01 16:13:02

+0

對於不需要命令,你是對的關於levels - 你可以在'arrange(a,b,c,...)'中使用多個參數,並且可以按你喜歡的方式進行排序(也許我只是看不到但我知道你的痛苦,因爲你已經排序了所有的東西...... – bergant 2015-04-01 17:16:32

+0

@bergant,對我來說,除排序之外的更大的問題是因子水平正在改變 – A5C1D2H2I1M1N2O1R2T1 2015-04-04 04:00:44

3

的順序是從因子水平的順序拍攝。

str(df) 
'data.frame': 4 obs. of 4 variables: 
$ name : Factor w/ 2 levels "A","B": 2 2 1 1 
$ group: Factor w/ 2 levels "g1","g2": 1 2 1 2 
$ V1 : num 10 40 20 30 
$ V2 : num 6 3 1 7 

看到水平是「A」,「B」。

所以,如果你的水平的順序設置與它們顯示在它的工作順序:在

df = data.frame(name=c("B","B","A","A"), 
       group=c("g1","g2","g1","g2"), 
       V1=c(10,40,20,30), 
       V2=c(6,3,1,7)) 

df %>% 
    mutate(name = factor(name,levels=unique(name))) %>% 
    mutate(group = factor(group,levels=unique(group))) %>% 
    gather(Var, Val, V1:V2) %>% 
    unite(VarG, Var, group) %>% 
    spread(VarG, Val) 

結果:

name V1_g1 V1_g2 V2_g1 V2_g2 
1 B 10 40  6  3 
2 A 20 30  1  7