Как изменить функциюmelt.data.frame в пакете reshape2, возвращающую столбец переменной в класс символов?

По умолчанию Melt.data.frame возвращает столбец «переменная» в классе «фактор». Вот пример:

> 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

> x = melt(head(airquality))
Using  as id variables

> head(x)
  variable value
1    ozone    41
2    ozone    36
3    ozone    12
4    ozone    18
5    ozone    NA
6    ozone    28

> class(x$variable)
[1] "factor"

Вопрос в том, есть ли какой параметр для смены класса с фактора на символ? Я пробовал options(stringsAsFactors = FALSE), но это не работает.


person rninja    schedule 14.09.2011    source источник


Ответы (2)


Я не верю, что такая опция встроена в melt.data.frame. Однако, если вы проверите код, его нетрудно изменить. Мы можем определить новую функцию melt.df, которая заменяет соответствующую строку быстрой проверкой, установил ли пользователь stringsAsFactors = FALSE:

if (getOption("stringsAsFactors")){
    df[[variable_name]] <- factor(df[[variable_name]], 
                                   unique(df[[variable_name]]))
}
else{
   df[[variable_name]] <- as.character(factor(df[[variable_name]],         
                                   unique(df[[variable_name]])))
}

Я проверил это на вашем простом примере, и он сработал, как и ожидалось, но я не проверял его в целом, так что будьте осторожны. Я не уверен, что эта модификация не приведет к неожиданному поведению в других обстоятельствах.

person joran    schedule 14.09.2011
comment
Я думаю, вам лучше обернуть расплав в другую функцию, которая делает df$variable <- as.character(df$variable) - person hadley; 16.09.2011
comment
@hadley, это неудобство при работе с датами. Однако работает. - person dmvianna; 09.12.2013
comment
@dmvianna, пожалуйста, отправьте сообщение о проблеме с небольшим примером на github.com/hadley/reshape/issues. - person hadley; 12.12.2013
comment
@hadley Непросто иметь универсальную оболочку: melt.data.frame имеет другое имя аргумента для столбца переменных, чем melt.matrix (variable.name против varnames). Было бы лучше, если бы фактическое melt можно было заставить использовать символы вместо множителя. - person Konrad Rudolph; 16.02.2015

Поскольку в наши дни большинство пользователей переходят либо к «tidyverse», либо к «data.table» для изменения формы данных, ваши возможности улучшились.

В «tidyverse» поведение по умолчанию — сохранить переменную molten как characters:

library(tidyverse)
airquality %>% gather(var, val, everything()) %>% str()
# 'data.frame': 918 obs. of  2 variables:
#  $ var: chr  "Ozone" "Ozone" "Ozone" "Ozone" ...
#  $ val: num  41 36 12 18 NA 28 23 19 8 NA ...

В реализации "data.table" melt было добавлено несколько новых аргументов, один из которых - variable.factor, которому можно присвоить значение FALSE. По умолчанию он установлен на TRUE, я полагаю, для согласованности с реализацией "reshape2" melt.

library(data.table)
str(melt(as.data.table(airquality), variable.factor = FALSE))
# Classes ‘data.table’ and 'data.frame':    36 obs. of  2 variables:
#  $ variable: chr  "Ozone" "Ozone" "Ozone" "Ozone" ...
#  $ value   : num  41 36 12 18 NA 28 190 118 149 313 ...
#  - attr(*, ".internal.selfref")=<externalptr> 
person A5C1D2H2I1M1N2O1R2T1    schedule 14.12.2017