tidyr::spread 和 dplyr::summarise 中的隐式排序
Implicit sorting in tidyr::spread and dplyr::summarise
我的数据是有序的观察结果,我想在进行操作时尽可能保持有序。
取 的答案,我在数据框中将 "B" 放在 "A" 之前。生成的宽数据按列 "name" 排序,即首先 "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
您可以根据原始数据框中的顺序按名称排序:
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
顺序取自因子水平的顺序。
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
tidyr::pivot_wider()
,建议替换 tidyr::spread()
,因为 tidyr 1.0.0,保持行的顺序,这样你就可以做:
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 创建
我的数据是有序的观察结果,我想在进行操作时尽可能保持有序。
取
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
您可以根据原始数据框中的顺序按名称排序:
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
顺序取自因子水平的顺序。
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
tidyr::pivot_wider()
,建议替换 tidyr::spread()
,因为 tidyr 1.0.0,保持行的顺序,这样你就可以做:
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 创建