Сравнение сборки (тидыра) и плавления (reshape2)

Мне нравится пакет reshape2, потому что он упростил жизнь. Обычно Хэдли вносил улучшения в свои предыдущие пакеты, которые позволяют упорядочить и ускорить выполнение кода. Я решил испытать tidyr и, судя по прочитанному, подумал, что gather очень похож на melt из reshape2. Но после прочтения документации я не могу заставить gather выполнять ту же задачу, что и melt.

Просмотр данных

Вот представление данных (фактические данные в форме dput в конце сообщения):

  teacher yr1.baseline     pd yr1.lesson1 yr1.lesson2 yr2.lesson1 yr2.lesson2 yr2.lesson3
1       3      1/13/09 2/5/09      3/6/09     4/27/09     10/7/09    11/18/09      3/4/10
2       7      1/15/09 2/5/09      3/3/09      5/5/09    10/16/09    11/18/09      3/4/10
3       8      1/27/09 2/5/09      3/3/09     4/27/09     10/7/09    11/18/09      3/5/10

Код

Вот код в стиле melt, моя попытка gather. Как я могу заставить gather делать то же самое, что и melt?

library(reshape2); library(dplyr); library(tidyr)

dat %>% 
   melt(id=c("teacher", "pd"), value.name="date") 

dat %>% 
   gather(key=c(teacher, pd), value=date, -c(teacher, pd)) 

Желаемый результат

   teacher     pd     variable     date
1        3 2/5/09 yr1.baseline  1/13/09
2        7 2/5/09 yr1.baseline  1/15/09
3        8 2/5/09 yr1.baseline  1/27/09
4        3 2/5/09  yr1.lesson1   3/6/09
5        7 2/5/09  yr1.lesson1   3/3/09
6        8 2/5/09  yr1.lesson1   3/3/09
7        3 2/5/09  yr1.lesson2  4/27/09
8        7 2/5/09  yr1.lesson2   5/5/09
9        8 2/5/09  yr1.lesson2  4/27/09
10       3 2/5/09  yr2.lesson1  10/7/09
11       7 2/5/09  yr2.lesson1 10/16/09
12       8 2/5/09  yr2.lesson1  10/7/09
13       3 2/5/09  yr2.lesson2 11/18/09
14       7 2/5/09  yr2.lesson2 11/18/09
15       8 2/5/09  yr2.lesson2 11/18/09
16       3 2/5/09  yr2.lesson3   3/4/10
17       7 2/5/09  yr2.lesson3   3/4/10
18       8 2/5/09  yr2.lesson3   3/5/10

Данные

dat <- structure(list(teacher = structure(1:3, .Label = c("3", "7", 
    "8"), class = "factor"), yr1.baseline = structure(1:3, .Label = c("1/13/09", 
    "1/15/09", "1/27/09"), class = "factor"), pd = structure(c(1L, 
    1L, 1L), .Label = "2/5/09", class = "factor"), yr1.lesson1 = structure(c(2L, 
    1L, 1L), .Label = c("3/3/09", "3/6/09"), class = "factor"), yr1.lesson2 = structure(c(1L, 
    2L, 1L), .Label = c("4/27/09", "5/5/09"), class = "factor"), 
        yr2.lesson1 = structure(c(2L, 1L, 2L), .Label = c("10/16/09", 
        "10/7/09"), class = "factor"), yr2.lesson2 = structure(c(1L, 
        1L, 1L), .Label = "11/18/09", class = "factor"), yr2.lesson3 = structure(c(1L, 
        1L, 2L), .Label = c("3/4/10", "3/5/10"), class = "factor")), .Names = c("teacher", 
    "yr1.baseline", "pd", "yr1.lesson1", "yr1.lesson2", "yr2.lesson1", 
    "yr2.lesson2", "yr2.lesson3"), row.names = c(NA, -3L), class = "data.frame")

person Tyler Rinker    schedule 23.10.2014    source источник
comment
Возможно, вас заинтересует это сравнение пакетов reshape2 и tidyr + dplyr. Я использовал пример качества воздуха и пример картофеля фри, чтобы сравнить использование функций reshape2 melt () и dcast () с функциями tidyr gather () и spread () в сочетании с функциями dplyr group_by () и summarize ().   -  person Paul Rougieux    schedule 22.01.2016


Ответы (2)


Ваша gather строка должна выглядеть так:

dat %>% gather(variable, date, -teacher, -pd)

Это говорит: «Соберите все переменные, кроме teacher и pd, вызывая новый ключевой столбец« переменная »и новый столбец значений« дата »».


В качестве пояснения обратите внимание на следующее на странице help(gather):

 ...: Specification of columns to gather. Use bare variable names.
      Select all variables between x and z with ‘x:z’, exclude y
      with ‘-y’. For more options, see the select documentation.

Поскольку это многоточие, спецификация собираемых столбцов дается как отдельные аргументы (пустое имя). Мы хотим собрать все столбцы, кроме teacher и pd, поэтому мы используем -.

person David Robinson    schedule 23.10.2014
comment
Теперь синтаксис имеет смысл. Я просто не видел этого раньше. Спасибо за потрясающий ответ. - person Tyler Rinker; 24.10.2014
comment
@BenBolker Мне это больше нравится. Это помогает мне группировать вещи в моем мозгу и, в конечном итоге, сокращается количество нажатий клавиш. - person Tyler Rinker; 24.10.2014

В tidyr 1.0.0 эта задача решена с помощью более гибкого pivot_longer().

Эквивалентный синтаксис будет

library(tidyr)
dat %>% pivot_longer(cols = -c(teacher, pd), names_to = "variable", values_to = "date")

который говорит, соответственно, «поверните все больше, кроме teacher и pd, вызывая новый столбец переменной« переменная »и столбец нового значения« дата ».

Обратите внимание, что длинные данные возвращаются в первую очередь столбцов предыдущего фрейма данных, которые были повернуты, в отличие от gather, который вернулся в порядке столбца новой переменной. Чтобы переставить получившийся тиббл, используйте dplyr::arrange().

person Joe    schedule 24.09.2019