tidyr 传播排序不一致
tidyr spread sorting inconsistencies
我注意到 tidyr(0.4.0)
在使用 spread
时对值列进行排序,而 tidyr(0.3.1)
returns 值列按照它们在 [=19= 之前的顺序排列].
可重现示例 1:
library(dplyr)
library(tidyr)
# tidyr 0.3.1
dat<-data.frame(name=rep(c("A","B"),5),sam.id=rep(c(1,2),5),
frac=sample(c(0.05,0.1,0.2),10,replace=TRUE),
Aspecies=rnorm(10),Bspecies=rnorm(10),Zspecies=rnorm(10))
我通过 sam.id
和 frac
(测量样本的比例)汇总物种值,即倍数 gather
。
dt.agg.0.3.1 <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>%
summarise(Total=sum(value)) %>% spread(key,Total) %>%
mutate(all=rowSums(.[,3:5]))
管道的最后一部分使用 mutate
计算所有物种的简单总数。这样:
head(dt.agg.0.3.1)
Source: local data frame [2 x 6]
name frac Aspecies Bspecies Zspecies all
(fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
1 A 0.85 -2.675137 -0.03287276 1.016791 -1.858010
2 B 0.40 4.194904 1.50561762 -2.738543 6.100522
可重现示例 2:
library(tidyr)
# 0.4.0
dt.agg.0.4.0 <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>%
summarise(Total=sum(value)) %>% spread(key,Total)
head(dt.agg.0.4.0)
Source: local data frame [2 x 5]
Groups: name [2]
name Aspecies Bspecies frac Zspecies
(fctr) (dbl) (dbl) (dbl) (dbl)
1 A -2.675137 -0.03287276 0.85 1.016791
2 B 4.194904 1.50561762 0.40 -2.738543
可以看到值列的顺序是如何更改的(按字母顺序),这使得使用 mutate
的额外数据管道步骤很麻烦。
dt.agg.0.4.0.mutated <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>% summarise(Total=sum(value)) %>%
spread(key,Total) %>% mutate(all=rowSums(.[,2:5]))
抛出错误;
Error: incompatible size (2), expecting 1 (the group size) or 1
有没有办法让tidyr(0.4.0)
按照gather
的顺序spread
退出?
或者必须 gather
(和 summarise
)两次——每个键值对一次?
我们可以在 spread
和 grep
需要用于 rowSums
(tidyr_0.4.0
) 的列之后使用 ungroup
。
gather(dat, key, value, -name, sam.id) %>%
group_by(name, key) %>%
summarise(Total=sum(value)) %>%
spread(key, Total) %>%
ungroup() %>%
mutate(all= rowSums(.[grep('species', names(.))]))
# name Aspecies Bspecies frac sam.id Zspecies all
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
#1 A 5.795958 -0.4769954 0.4 5 3.965114 9.284077
#2 B 2.475395 -1.4858969 0.5 10 1.045175 2.034674
如果我们需要获得列在 'key' 列中的顺序,那么我们可能需要将 'key' 转换为 factor
class指定了 levels
。在这种情况下,我们可以使用 rowSums
.
中的位置索引
gather(dat,key,value,-name,-sam.id) %>%
mutate(key= factor(key, levels=unique(key))) %>%
group_by(name, key) %>%
summarise(Total = sum(value)) %>%
spread(key, Total) %>%
ungroup() %>%
mutate(all = rowSums(.[3:5]))
#Source: local data frame [2 x 6]
# name frac Aspecies Bspecies Zspecies all
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
#1 A 0.4 5.795958 -0.4769954 3.965114 9.284077
#2 B 0.5 2.475395 -1.4858969 1.045175 2.034674
如果我们在 spread
步骤之后查看 str
,即
res <- gather(dat, key, value, -name, sam.id) %>%
group_by(name, key) %>%
summarise(Total=sum(value)) %>%
spread(key, Total)
str(res)
#Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 6 variables:
#...
其中一个 class
是 'grouped_df',它以某种方式造成了问题。
str(res %>% ungroup)
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 6 variables:
注意:这些值与 OP 的 post 不同,因为未指定 set.seed
。
我注意到 tidyr(0.4.0)
在使用 spread
时对值列进行排序,而 tidyr(0.3.1)
returns 值列按照它们在 [=19= 之前的顺序排列].
可重现示例 1:
library(dplyr)
library(tidyr)
# tidyr 0.3.1
dat<-data.frame(name=rep(c("A","B"),5),sam.id=rep(c(1,2),5),
frac=sample(c(0.05,0.1,0.2),10,replace=TRUE),
Aspecies=rnorm(10),Bspecies=rnorm(10),Zspecies=rnorm(10))
我通过 sam.id
和 frac
(测量样本的比例)汇总物种值,即倍数 gather
。
dt.agg.0.3.1 <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>%
summarise(Total=sum(value)) %>% spread(key,Total) %>%
mutate(all=rowSums(.[,3:5]))
管道的最后一部分使用 mutate
计算所有物种的简单总数。这样:
head(dt.agg.0.3.1)
Source: local data frame [2 x 6]
name frac Aspecies Bspecies Zspecies all
(fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
1 A 0.85 -2.675137 -0.03287276 1.016791 -1.858010
2 B 0.40 4.194904 1.50561762 -2.738543 6.100522
可重现示例 2:
library(tidyr)
# 0.4.0
dt.agg.0.4.0 <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>%
summarise(Total=sum(value)) %>% spread(key,Total)
head(dt.agg.0.4.0)
Source: local data frame [2 x 5]
Groups: name [2]
name Aspecies Bspecies frac Zspecies
(fctr) (dbl) (dbl) (dbl) (dbl)
1 A -2.675137 -0.03287276 0.85 1.016791
2 B 4.194904 1.50561762 0.40 -2.738543
可以看到值列的顺序是如何更改的(按字母顺序),这使得使用 mutate
的额外数据管道步骤很麻烦。
dt.agg.0.4.0.mutated <- gather(dat,key,value,-name,-sam.id) %>%
group_by(name,key) %>% summarise(Total=sum(value)) %>%
spread(key,Total) %>% mutate(all=rowSums(.[,2:5]))
抛出错误;
Error: incompatible size (2), expecting 1 (the group size) or 1
有没有办法让tidyr(0.4.0)
按照gather
的顺序spread
退出?
或者必须 gather
(和 summarise
)两次——每个键值对一次?
我们可以在 spread
和 grep
需要用于 rowSums
(tidyr_0.4.0
) 的列之后使用 ungroup
。
gather(dat, key, value, -name, sam.id) %>%
group_by(name, key) %>%
summarise(Total=sum(value)) %>%
spread(key, Total) %>%
ungroup() %>%
mutate(all= rowSums(.[grep('species', names(.))]))
# name Aspecies Bspecies frac sam.id Zspecies all
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
#1 A 5.795958 -0.4769954 0.4 5 3.965114 9.284077
#2 B 2.475395 -1.4858969 0.5 10 1.045175 2.034674
如果我们需要获得列在 'key' 列中的顺序,那么我们可能需要将 'key' 转换为 factor
class指定了 levels
。在这种情况下,我们可以使用 rowSums
.
gather(dat,key,value,-name,-sam.id) %>%
mutate(key= factor(key, levels=unique(key))) %>%
group_by(name, key) %>%
summarise(Total = sum(value)) %>%
spread(key, Total) %>%
ungroup() %>%
mutate(all = rowSums(.[3:5]))
#Source: local data frame [2 x 6]
# name frac Aspecies Bspecies Zspecies all
# (fctr) (dbl) (dbl) (dbl) (dbl) (dbl)
#1 A 0.4 5.795958 -0.4769954 3.965114 9.284077
#2 B 0.5 2.475395 -1.4858969 1.045175 2.034674
如果我们在 spread
步骤之后查看 str
,即
res <- gather(dat, key, value, -name, sam.id) %>%
group_by(name, key) %>%
summarise(Total=sum(value)) %>%
spread(key, Total)
str(res)
#Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 6 variables:
#...
其中一个 class
是 'grouped_df',它以某种方式造成了问题。
str(res %>% ungroup)
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 6 variables:
注意:这些值与 OP 的 post 不同,因为未指定 set.seed
。