2

Why melt() converts dimension names from small to capital letters? How can that be avoided? See example below. Thanks!

library(data.table)

# an array which dimnames are mixed numeric and characters (e.g. "inf")
ax <- array(round(rnorm(12)), dim = c(3,4), dimnames = list(y = c(0,1,"inf"), x = letters[4:7]))

# melt converts "inf" to "Inf"
dt <- setDT(melt(ax))
> head(dt)
    y x value
1   0 d     0
2   1 d    -1
3 Inf d     1
4   0 e     0
5   1 e     2
6 Inf e    -1
Sara
  • 465
  • 5
  • 15
  • 1
    Note that `Inf` holds a special name in `R`, melt probably assumes `inf` is `Inf` so maybe change the dimnames. – s_baldur Jul 27 '18 at 09:56
  • 1
    Or rename your `"inf"` like this `"'inf'"` – Miha Jul 27 '18 at 09:57
  • 1
    If required apply `tolower` on that particular column after `melt`. – msr_003 Jul 27 '18 at 10:03
  • make sense, all answers helpful! `tolower` solved the issue nicely. I agree using inf is not a good idea for dimnames. Thanks for pointing it out : ) – Sara Jul 27 '18 at 10:14
  • 1
    Also note that the result of `melt(ax)` is NOT a data.table because `ax` is an array. `print(melt)` shows that `reshape2::melt()` is dispatched for non-data.table arguments. – Uwe Jul 27 '18 at 10:46
  • @Uwe right, sorry that was for conciseness, since the issue occurs within `melt`. I'm actually using it with `setDT(melt(array))` as I've learned here: https://stackoverflow.com/questions/51247677/how-to-convert-array-to-data-table-in-r-and-back – Sara Jul 27 '18 at 11:12

1 Answers1

3

Reading ?melt.array shows this option:

as.is

if FALSE, the default, dimnames will be converted using type.convert. [See ?type.convert.] If TRUE, they will be left as strings.

melt(ax, as.is = TRUE)

     y x value
1    0 d     1
2    1 d     1
3  inf d     0
4    0 e     0
5    1 e     2
6  inf e     0
7    0 f     0
8    1 f    -1
9  inf f     0
10   0 g     1
11   1 g    -1
12 inf g    -1

So this behavior is from type.convert(c("0", "1", "inf")) from the base package utils. From ?type.convert:

Other vectors containing optional whitespace followed by other decimal or hexadecimal constants (see ?NumericConstants), or NaN, Inf or infinity (ignoring case) or values from na.strings are converted to numeric.

Frank
  • 66,179
  • 8
  • 96
  • 180