tidyr中的隐式排序:: spread和dplyr :: summarize

时间:2015-04-01 00:50:03

标签: r dplyr data-manipulation tidyr

我的数据是有序的观察结果,我希望在进行操作时尽可能保持顺序。

得到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

3 个答案:

答案 0 :(得分:10)

您可以根据原始数据框中的顺序按名称排序:

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 :(得分:9)

订单取自因子水平的顺序。

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

答案 2 :(得分:0)

tidyr::pivot_wider()是自 tidyr 1.0.0 起推荐的tidyr::spread()的替换,它使行保持顺序,以便您可以执行以下操作:

library(tidyr)

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))

pivot_wider(df, names_from = "group", values_from = c("V1", "V2"))
#> # A tibble: 2 x 5
#>   name  V1_g1 V1_g2 V2_g1 V2_g2
#>   <fct> <dbl> <dbl> <dbl> <dbl>
#> 1 B        10    40     6     3
#> 2 A        20    30     1     7

reprex package(v0.3.0)于2019-09-14创建