我已经注意到,使用tidyr(0.4.0)spread对值列进行排序,因为tidyr(0.3.1)以它们在gather之前的顺序返回值列。

可重现的示例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.idfrac(所测样品的比例)(即多个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)按照spread的顺序退回gather

还是必须两次gather(和summarise)-每个键值对一次?

最佳答案

我们可以在ungroupspread需要用于greprowSums)的列之后使用tidyr_0.4.0

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


如果我们需要获取“键”列中出现的列的顺序,则可能需要将“键”转换为指定了factorlevels类。在这种情况下,我们可以使用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




如果我们在str步骤之后查看spread,即

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的帖子不同,因为未指定set.seed

关于r - 提迪尔散布排序不一致,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35103523/

10-12 12:24