2016-01-30 2 views
3

Ive заметил tidyr(0.4.0) сортирует значения столбцов при использовании spread, где tidyr(0.3.1) возвращает столбцы значений в порядке, который был до gather.tidyr spread сортировки несоответствий

Воспроизводимый Пример 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) к spread обратно в порядке, в gather?

Или должен будет gathersummarise) дважды - один раз для каждой пары ключ-значение?

ответ

2

Мы можем использовать ungroup после spread и grep колонн, которые необходимо использовать для rowSums (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 

Если нам нужно, чтобы получить порядок столбцов, что происходит в колонке «ключ», то, возможно, потребуется преобразовать «ключ» к 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 

Если мы посмотрим на 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: 

ПРИМЕЧАНИЕ: Значения отличаются от должности операционного как не set.seed не было указано.

+0

большой! Я буду использовать 'mutate (key = factor (key, levels = unique (key))), поскольку фактические названия видов различаются, но скорее упорядочены в последовательных столбцах ... –

+1

@kleanBean 'unique (key)' будет упорядочивать элементы в 'key', как он появляется в столбце. Если вам нужен индивидуальный заказ, укажите уровни по мере необходимости. то есть 'levels = c ('frac', 'Aspecies', 'Somethingelse' ...' Что касается разницы в обеих версиях, это может быть ошибкой. – akrun