рекомендации

среда, 28 ноября 2018 г.

Введение в пакет reshape2

reshape2 представляет собой пакет R, написанный Хэдли Викхэмом, который упрощает преобразование данных между широкими и длинными форматами. 
  
Что делает данные широкими или длинными? 
  
У широких данных есть столбец для каждой переменной. Например, это данные в широком формате: 
  
## ozone wind temp  
## 1 23.61538 11.622581 65.54839  
## 2 29.44444 10.266667 79.10000  
## 3 59.11538 8.941935 83.90323  
## 4 59.96154 8.793548 83.96774 
  
А это данные в длинном формате: 
  
#    variable  value 
# 1     ozone 23.615 
# 2     ozone 29.444 
# 3     ozone 59.115 
# 4     ozone 59.962 
# 5      wind 11.623 
# 6      wind 10.267 
# 7      wind  8.942 
# 8      wind  8.794 
# 9      temp 65.548 
# 10     temp 79.100 
# 11     temp 83.903 
# 12     temp 83.968 
  
У длинноформатных данных есть столбец возможных типов переменных и столбец для значений этих переменных. Длинные данные не обязательно должны содержать только два столбца. Например, у нас могут быть измерения озона за каждый день года. В этом случае у нас может быть другая колонка на день. Другими словами, существуют разные уровни «долготы». Конечная форма, в которую вы хотите преобразовать свои данные, будет зависеть от того, что вы собираетесь с ними делать. 
  
Оказывается, широкоформатные данные нужны для одних типов анализа данных, а длинноформатные данные для других. На самом длинноформатные данные нужны гораздо чаще, чем широкоформатные данные. Например, ggplot2 требует длинноформатных данных, plyr требует длинноформатных данных, и большинство функций моделирования (таких как lm(), glm() и gam()) требуют длинноформатных данных. Но людям часто легче записывать свои данные в широком формате. 
  
Пакет reshape2 
  
reshape2 основан на двух ключевых функциях: melt и cast: 
  
melt принимает широкоформатные данные и преобразует их в длинноформатные данные. 
  
cast принимает длинноформатные данные и преобразует их в широкоформатные данные. 
  
Преобразование широкоформатных данных в длинноформатные: функция melt 
  
В этом примере мы будем работать с набором данных airquality, который встроен в R. Сначала мы изменим имена столбцов на нижний регистр, чтобы упростить работу. Затем мы рассмотрим наши данные: 
  
names(airquality) <- nbsp="" span="">tolower(names(airquality)) 
head(airquality) 
  
#   ozone solar.r wind temp month day 
# 1    41     190  7.4   67     5   1 
# 2    36     118  8.0   72     5   2 
# 3    12     149 12.6   74     5   3 
# 4    18     313 11.5   62     5   4 
# 5    NA      NA 14.3   56     5   5 
# 6    28      NA 14.9   66     5   6 
  
Что произойдет, если мы запустим функцию melt со значениями аргументов по умолчанию? 
  
aql <- nbsp="" span="">melt(airquality) 
  
head(aql) 
  
#   variable value 
# 1    ozone    41 
# 2    ozone    36 
# 3    ozone    12 
# 4    ozone    18 
# 5    ozone    NA 
# 6    ozone    28 
  
tail(aql) 
  
#     variable value 
# 913      day    25 
# 914      day    26 
# 915      day    27 
# 916      day    28 
# 917      day    29 
# 918      day    30 
  
По умолчанию melt предполагает, что все столбцы с числовыми значениями являются переменными со значениями. Часто это то, что вы хотите. Возможно, здесь мы хотим знать значения озона, солнечного света, ветра и температуры для каждого месяца и дня. Мы можем сделать это с помощью melt, сказав, что мы хотим, чтобы месяц и день были «идентификационными переменными». Идентификационные переменные (ID) - это переменные, которые идентифицируют отдельные строки данных. 
  
aql <- nbsp="" span="">melt(airqualityid.vars = c("month", "day")) 
head(aql) 
  
#   month day variable value 
# 1     5   1    ozone    41 
# 2     5   2    ozone    36 
# 3     5   3    ozone    12 
# 4     5   4    ozone    18 
# 5     5   5    ozone    NA 
# 6     5   6    ozone    28 
  
Что, если мы хотим управлять именами столбцов в наших длинноформатных данных? melt позволяет нам сделать все это за один шаг: 
  
aql <- nbsp="" span="">melt(airqualityid.vars = c("month", "day"), 
  variable.name = "climate_variable",  
  value.name = "climate_value") 
head(aql) 
  
#   month day climate_variable climate_value 
# 1     5   1            ozone            41 
# 2     5   2            ozone            36 
# 3     5   3            ozone            12 
# 4     5   4            ozone            18 
# 5     5   5            ozone            NA 
# 6     5   6            ozone            28 
  
Преобразование длинноформатных данных в широкоформатные: функции cast 
  
В то время как переход от широкоформатных данных довольно прост, переход от длинноформатных данных может занять немного больше времени. Обычно это связано с некоторыми ошибками, кроме самых простых случаев. Давайте рассмотрим некоторые примеры. 
  
В reshape2 есть несколько функций cast. Поскольку вы чаще всего работаете с объектами data.frame, мы рассмотрим функцию dcast (есть также acast для векторов, матриц или массивов). 
  
Давайте возьмем данные airquality в длинном формате и переведем их в несколько широких форматов. Для начала мы восстановим тот же формат, с которого мы начали, и сравним их. 
  
dcast использует формулу для описания формы данных. Аргументы слева относятся к идентификационным переменным, а аргументы справа относятся к измеряемым переменным. Придумывая правильную формулу, вы можете сначала попробовать создать ее методом проб и ошибок. Итак, если вы застряли на этом месте, не огорчайтесь, просто экспериментируйте с формулами. Обычно существует много способов написать формулу. 
  
Здесь нам нужно сообщить dcast, что месяц и день - это идентификационные переменные (для каждой требуется столбец), и эта переменная описывает измеряемые переменные. Поскольку есть только один оставшийся столбец, dcast поймет, что он содержит сами значения. Мы могли бы явно объявить это с помощью value.var (и в некоторых случаях это необходимо будет сделать.) 
  
aql <- nbsp="" span="">melt(airqualityid.vars = c("month", "day")) 
aqw <- nbsp="" span="">dcast(aqlmonth + day ~ variable) 
head(aqw) 
  
#   month day ozone solar.r wind temp 
# 1     5   1    41     190  7.4   67 
# 2     5   2    36     118  8.0   72 
# 3     5   3    12     149 12.6   74 
# 4     5   4    18     313 11.5   62 
# 5     5   5    NA      NA 14.3   56 
# 6     5   6    28      NA 14.9   66 
  
head(airquality) # исходные данные 
  
#   ozone solar.r wind temp month day 
# 1    41     190  7.4   67     5   1 
# 2    36     118  8.0   72     5   2 
# 3    12     149 12.6   74     5   3 
# 4    18     313 11.5   62     5   4 
# 5    NA      NA 14.3   56     5   5 
# 6    28      NA 14.9   66     5   6 
  
Таким образом, помимо перестройки столбцов, мы восстановили исходные данные. 
  
Если вам не ясно, что там произошло, посмотрите эту иллюстрацию: 
  
Рисунок 1: Иллюстрация работы функции dcast. Синий цвет указывает на идентификационные переменные, которые мы хотим представлять в виде отдельных строк. Красный цвет представляет имена переменных, которые мы хотим превратить в имена столбцов. Серый цвет представляет значения данных, которыми мы хотим заполнить ячейки. 
  
Одна частая «ошибка», которую вы можете сделать, - это пытаться обработать набор данных, в котором на каждую ячейку данных имеется более одного значения. Например, на этот раз мы не будем включать день как идентификационную переменную: 
  
dcast(aqlmonth ~ variable) 
  
#   month ozone solar.r wind temp 
# 1     5    31      31   31   31 
# 2     6    30      30   30   30 
# 3     7    31      31   31   31 
# 4     8    31      31   31   31 
# 5     9    30      30   30   30 
  
Запустив эту команду в R, вы увидите предупреждающее сообщение: 
  
Aggregation function missingdefaulting to length 
  
И если вы посмотрите на результат, ячейки заполняются строками данных для каждой комбинации месяца и климата. Число, которое мы видим, - это количество дней, записанных в каждом месяце. Когда вы вводите свои данные и есть несколько значений на ячейку, вам также нужно сообщить dcast, как агрегировать данные. Например, возможно, вы хотите взять среднее значение, или медиану, или сумму. Давайте попробуем последний пример, но на этот раз мы возьмем средние значения климата. Мы также передадим параметр na.rm = TRUE через ... argument, чтобы удалить значения NA. 
  
dcast(aqlmonth ~ variablefun.aggregate = mean 
  na.rm = TRUE) 
  
#   month ozone solar.r   wind  temp 
# 1     5 23.62   181.3 11.623 65.55 
# 2     6 29.44   190.2 10.267 79.10 
# 3     7 59.12   216.5  8.942 83.90 
# 4     8 59.96   171.9  8.794 83.97 
# 5     9 31.45   167.4 10.180 76.90 
  
В отличие от melt, есть разные причудливые штуки, которые вы можете сделать с dcast, которые я здесь не раскрываю. Стоит прочитать файл справки ?dcast. Например, вы можете вычислять различные показатели для строк и столбцов, выделять подмножество столбцов и заполнять отсутствующие ячейки одним вызовом dcast. 
  
Дополнительная информация 
  
Помощь по пакету reshape2: help(package = "reshape2") 
  
Сайт reshape2: http://had.co.nz/reshape/ 

Комментариев нет:

Отправить комментарий