为 melt/gather 中的新列指定 class

Specify class for new columns in melt/gather

我想在 melt(或 gather)中指定输出列的 class。我想对所有列和不同的 classes.

执行此操作

比如我有一些数据:

example <- data.frame(day = c(1, 2), max = c(20, 21), min = c(1, 2))

> example
  day max min
1   1  20   1
2   2  21   2

我融化了那些数据

exmelt <- melt(example, id.vars = "day", variable.name = "minmax", value.name = "temp")

> exmelt
  day minmax temp
1   1    max   20
2   2    max   21
3   1    min    1
4   2    min    2

 > str(exmelt)
'data.frame':   4 obs. of  3 variables:
 $ day   : num  1 2 1 2
 $ minmax: Factor w/ 2 levels "max","min": 1 1 2 2
 $ temp  : num  20 21 1 2

假设我希望 day 是 class 因子,temp 是 class 整数

我可以用as.factor()

融化后做这个
exmelt$day <- as.factor(exmelt$day)
exmelt$temp <- as.integer(exmelt$temp)

> str(exmelt)
'data.frame':   4 obs. of  3 variables:
$ day   : Factor w/ 2 levels "1","2": 1 2 1 2
$ minmax: Factor w/ 2 levels "max","min": 1 1 2 2
$ temp  : int  20 21 1 2

之后对包含许多列和不同 classes、一些因子、一些整数等的复杂数据框执行此操作将是乏味和混乱的。

有没有办法将其包含在 melt 中?比如

 melt(example,
      id.vars = "day",
      variable.name = "minmax",
      value.name = "temp",
      colClasses = c("factor", "factor", "integer"))

我们可以使用 data.table 中的 melt,它也有选项 variable.factorvalue.factor。除此之外,colClasses 不是其中的参数。

dM <- melt(setDT(example), id.vars = "day", variable.name = "minmax",
           value.name = "temp", variable.factor=FALSE)

但是,假设我们需要一步完成,创建一个 vector 函数,然后使用 Mapget

应用它
f1 <- c("as.factor", "as.factor", "as.integer")
dM[, names(dM) := Map(function(x,y) get(y)(x), .SD, f1)]
str(dM)
# Classes ‘data.table’ and 'data.frame':  4 obs. of  3 variables:
# $ day   : Factor w/ 2 levels "1","2": 1 2 1 2
# $ minmax: Factor w/ 2 levels "max","min": 1 1 2 2
# $ temp  : int  20 21 1 2