Skip to content

Commit

Permalink
Closes #780. Consistency with reshape2's melt.
Browse files Browse the repository at this point in the history
  • Loading branch information
arunsrinivasan committed Aug 21, 2014
1 parent b9e632d commit f2cbe5e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 10 deletions.
14 changes: 8 additions & 6 deletions R/fmelt.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
melt.data.table <- function(data, id.vars = NULL, measure.vars = NULL, variable.name = "variable",
melt.data.table <- function(data, id.vars, measure.vars, variable.name = "variable",
value.name = "value", ..., na.rm = FALSE, variable.factor = TRUE, value.factor = FALSE,
verbose = getOption("datatable.verbose")) {
drop.levels <- FALSE # maybe a future FR
if (!inherits(data, "data.table")) stop("'data' must be a data.table")
ans <- .Call("Cfmelt", data, id.vars, measure.vars,
as.logical(variable.factor), as.logical(value.factor),
variable.name, value.name,
as.logical(na.rm), as.logical(drop.levels),
as.logical(verbose));
if (missing(id.vars)) id.vars=NULL
if (missing(measure.vars)) measure.vars = NULL
ans <- .Call("Cfmelt", data, id.vars, measure.vars,
as.logical(variable.factor), as.logical(value.factor),
variable.name, value.name,
as.logical(na.rm), as.logical(drop.levels),
as.logical(verbose));
setattr(ans, "row.names", .set_row_names(length(ans[[1L]])))
setattr(ans, "class", c("data.table", "data.frame"))
alloc.col(ans)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ We moved from R-Forge to GitHub on 9 June 2014, including history.
44. Subset on data.table using `lapply` of the form `lapply(L, "[", Time == 3L)` works now without error due to "[.data.frame" redirection. Closes [#500](https://github.com/Rdatatable/data.table/issues/500). Thanks to Garrett See for reporting.
45. `id.vars` and `measure.vars` default value of `NULL` was removed to be consistent in behaviour with `reshape2:::melt.data.frame`. Closes [#780](https://github.com/Rdatatable/data.table/issues/500). Thanks to @dardesta for reporting.
#### NOTES
1. Reminder: using `rolltolast` still works but since v1.9.2 now issues the following warning:
Expand Down
11 changes: 11 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -5110,6 +5110,17 @@ for (i in seq_along(dt)) {
})
}

# fix for #780.
if ("package:reshape2" %in% search()) {
try(detach(package:reshape),silent=TRUE)
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
foo = function(input, by, var) {
melt(input, id.vars = by, measure.vars=var)
}
test(1371.1, foo(DT, by="x"), data.table(x=rep(DT$x, 2L), variable=factor(rep(c("y", "v"), each=9L), levels=c("y", "v")), value=c(DT$y, DT$v)), warning="All 'measure.vars are NOT of the SAME type.")
test(1371.2, foo(DT), data.table(x=rep(DT$x, 2L), variable=factor(rep(c("y", "v"), each=9L), levels=c("y", "v")), value=c(DT$y, DT$v)), warning="To be consistent with reshape2's melt, id.vars and")
}

##########################


Expand Down
8 changes: 4 additions & 4 deletions man/melt.data.table.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
}
\usage{
## fast melt a data.table
\method{melt}{data.table}(data, id.vars = NULL, measure.vars = NULL,
\method{melt}{data.table}(data, id.vars, measure.vars,
variable.name = "variable", value.name = "value",
..., na.rm = FALSE, variable.factor = TRUE,
value.factor = FALSE,
verbose = getOption("datatable.verbose"))
}
\arguments{
\item{data}{ A \code{data.table} object to melt.}
\item{id.vars}{vector of id variables. Can be integer (corresponding id column numbers) or character (id column names) vector. If \code{NULL}, all non-measure columns will be assigned to it.}
\item{measure.vars}{vector of measure variables. Can be integer (corresponding measue column numbers) or character (measure column names) vector. If \code{NULL}, all non-id columns will be assigned to it.}
\item{id.vars}{vector of id variables. Can be integer (corresponding id column numbers) or character (id column names) vector. If missing, all non-measure columns will be assigned to it.}
\item{measure.vars}{vector of measure variables. Can be integer (corresponding measue column numbers) or character (measure column names) vector. If missing, all non-id columns will be assigned to it.}
\item{variable.name}{name for the measured variable names column. The default name is 'variable'.}
\item{value.name}{name for the molten data values column. The default name is 'value'.}
\item{na.rm}{If \code{TRUE}, \code{NA} values will be removed from the molten data.}
Expand All @@ -26,7 +26,7 @@
\item{...}{any other arguments to be passed to/from other methods}
}
\details{
If \code{id.vars} and \code{measure.vars} are both \code{NULL}, all non-\code{numeric/integer/logical} columns are assigned as id variables and the rest of the columns are assigned as measure variables. If only one of \code{id.vars} or \code{measure.vars} is supplied, the rest of the columns will be assigned to the other. Both \code{id.vars} and \code{measure.vars} can have the same column more than once and same column can be as id and measure variables.
If \code{id.vars} and \code{measure.vars} are both missing, all non-\code{numeric/integer/logical} columns are assigned as id variables and the rest of the columns are assigned as measure variables. If only one of \code{id.vars} or \code{measure.vars} is supplied, the rest of the columns will be assigned to the other. Both \code{id.vars} and \code{measure.vars} can have the same column more than once and same column can be as id and measure variables.

\code{melt.data.table} also accepts \code{list} columns for both id and measure variables. When all \code{measure.vars} are not of the same type, they'll be coerced according to the hierarchy \code{list} > \code{character} > \code{numeric > integer > logical}. For example, any of the measure variables is a \code{list}, then entire value column will be coerced to a list. Note that, if the type of \code{value} column is a list, \code{na.rm = TRUE} will have no effect.
Expand Down

0 comments on commit f2cbe5e

Please sign in to comment.