How to change the melt.data.frame function in reshape2 package returned "variable" column to "character" class?
The default b开发者_JS百科ehavior of melt.data.frame is to return the "variable" column in "factor" class. Here is an example:
> 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"
The question is that is there any parameter to change the class from factor to character? I tried options(stringsAsFactors = FALSE)
but it is not working.
I don't believe there is such an option built into melt.data.frame
. However, if you inspect the code, it's not hard to change. We can define a new function melt.df
that replaces the relevant line with a quick check to see if the user has set 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]])))
}
I checked this on your simple example and it worked as expected, but I haven't checked it more generally, so beware. I'm not convinced this modification won't produce surprising behavior in other circumstances.
With most users heading over to either the "tidyverse" or "data.table" for reshaping data these days, your options have improved.
In the "tidyverse", the default behavior is to keep the molten variable as character
s:
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 ...
In the "data.table" implementation of melt
, a few new arguments have been added, one of which is variable.factor
which can be set to FALSE
. It's set to TRUE
by default for, I believe, consistency with the "reshape2" implementation of 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>
精彩评论