【问题标题】:tidyr spread sorting inconsistenciestidyr 传播排序不一致
【发布时间】:2016-01-30 15:30:08
【问题描述】:

我注意到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)spreadgather 的顺序退出?

或者必须gather(和summarise)两次——每个键值对一次?

【问题讨论】:

    标签: r key-value tidyr spread


    【解决方案1】:

    我们可以在spreadgrep 需要用于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类并指定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 的帖子不同,因为没有指定 set.seed

    【讨论】:

    • 太棒了!我将使用mutate(key= factor(key, levels=unique(key))),因为实际的物种名称各不相同,而是按顺序排列...
    • @kleanBean unique(key) 将对key 中的元素进行排序,因为它出现在列中。如果您需要自定义订单,请根据需要指定级别。即levels = c('frac', 'Aspecies', 'Somethingelse'...关于两个版本的差异,这可能是一个错误..
    • 现在gather() factor_key=T 的参数也保留了原始顺序。
    猜你喜欢
    • 1970-01-01
    • 2016-05-21
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2020-01-19
    相关资源
    最近更新 更多