开发者

How to change the melt.data.frame function in reshape2 package returned "variable" column to "character" class?

开发者 https://www.devze.com 2023-04-05 11:17 出处:网络
The default b开发者_JS百科ehavior of melt.data.frame is to return the \"variable\" column in \"factor\" class. Here is an example:

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 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 ...

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> 
0

精彩评论

暂无评论...
验证码 换一张
取 消