reshape2/0000755000176200001440000000000015105023433011757 5ustar liggesusersreshape2/tests/0000755000176200001440000000000015104637043013130 5ustar liggesusersreshape2/tests/testthat/0000755000176200001440000000000015105023433014761 5ustar liggesusersreshape2/tests/testthat/test-melt.r0000644000176200001440000001467015104637331017101 0ustar liggesuserstest_that("Missing values removed when na.rm = TRUE", { v <- c(1:3, NA) expect_equal(melt(v)$value, v) expect_equal(melt(v, na.rm = TRUE)$value, 1:3) m <- matrix(v, nrow = 2) expect_equal(melt(m)$value, v) expect_equal(melt(m, na.rm = TRUE)$value, 1:3) l1 <- list(v) expect_equal(melt(l1)$value, v) expect_equal(melt(l1, na.rm = TRUE)$value, 1:3) l2 <- as.list(v) expect_equal(melt(l2)$value, v) expect_equal(melt(l2, na.rm = TRUE)$value, 1:3) df <- data.frame(x = v) expect_message( expect_equal(melt(df)$value, v), "No id variables", fixed = TRUE ) expect_message( expect_equal(melt(df, na.rm = TRUE)$value, 1:3), "No id variables", fixed = TRUE ) }) test_that("value col name set by value.name", { v <- c(1:3, NA) expect_equal(names(melt(v, value.name = "v")), "v") m <- matrix(v, nrow = 2) expect_equal(names(melt(m, value.name = "v"))[3], "v") l1 <- list(v) expect_equal(names(melt(l1, value.name = "v"))[1], "v") df <- data.frame(x = v) expect_message( expect_equal(names(melt(df, value.name = "v"))[2], "v"), "No id variables", fixed = TRUE ) }) test_that("lists can have zero element components", { l <- list(a = 1:10, b = integer(0)) m <- melt(l) expect_equal(nrow(m), 10) }) test_that("factors coerced to characters, not integers", { df <- data.frame( id = 1:3, v1 = 1:3, v2 = factor(letters[1:3])) expect_warning(dfm <- melt(df, 1)) expect_equal(dfm$value, c(1:3, letters[1:3])) }) test_that("dimnames are preserved with arrays and tables", { a <- array(c(1:12), c(2,3,2)) # Plain array with no dimnames am <- melt(a) expect_equal(names(am), c("Var1", "Var2", "Var3", "value")) # Also check values expect_equal(unique(am$Var1), 1:2) expect_equal(unique(am$Var2), 1:3) expect_equal(unique(am$Var3), 1:2) # Explicitly set varnames am <- melt(a, varnames = c("X", "Y", "Z")) expect_equal(names(am), c("X", "Y", "Z", "value")) # Set the dimnames for the array b <- a dimnames(b) <- list(X = c("A", "B"), Y = c("A", "B", "C"), Z = c("A", "B")) bm <- melt(b) expect_equal(names(bm), c("X", "Y", "Z", "value")) # Also check values expect_equal(levels(bm$X), c("A", "B")) expect_equal(levels(bm$Y), c("A", "B", "C")) expect_equal(levels(bm$Z), c("A", "B")) # Make sure the same works for contingency tables b <- as.table(a) dimnames(b) <- list(X = c("A", "B"), Y = c("A", "B", "C"), Z = c("A", "B")) bm <- melt(b) expect_equal(names(bm), c("X", "Y", "Z", "value")) # Also check values expect_equal(levels(bm$X), c("A", "B")) expect_equal(levels(bm$Y), c("A", "B", "C")) expect_equal(levels(bm$Z), c("A", "B")) }) test_that("dimnames kept in original order", { x <- matrix(1:4, nrow = 2) rownames(x) <- c("b", "a") colnames(x) <- c("e", "d") names(dimnames(x)) <- c("x", "y") m <- melt(x) expect_equal(levels(m$x), c("b", "a")) expect_equal(levels(m$y), c("e", "d")) }) test_that("as.is = TRUE suppresses dimnname conversion", { x <- matrix(nrow = 2, ncol = 2) dimnames(x) <- list(x = 1:2, y = 3:4) out <- melt(x, as.is = TRUE) expect_true(is.character(out$x)) expect_true(is.character(out$y)) }) test_that("The 'variable' column is a factor after melting a data.frame", { df <- data.frame(x=1:3, y=4:6) expect_message( expect_true( is.factor(melt(df)$variable) ), "No id variables", fixed = TRUE ) }) test_that("Common classes are preserved in measure variables", { df <- data.frame(id = 1:2, date1 = Sys.Date(), date2 = Sys.Date() + 10) m <- melt(df, measure.vars=c("date1", "date2")) expect_true( class(m$value) == "Date" ) }) test_that("Common attributes are preserved in measure variables", { df <- data.frame( id = 1:2, date1 = as.POSIXct( Sys.Date() ), date2 = as.POSIXct( Sys.Date() + 10) ) m <- melt(df, measure.vars=c("date1", "date2")) expect_s3_class(m$value, "POSIXct") }) test_that("A warning is thrown when attributes are dropped in measure variables", { df <- data.frame( id=1:2, date1 = as.POSIXct( Sys.Date() ), date2 = Sys.Date() + 10 ) expect_warning( melt(df, measure.vars=c("date1", "date2")) ) }) test_that("factorsAsStrings behaves as expected", { ## factors with identical levels -> staying as factor is okay df <- data.frame( id=1:2, f1=factor(c("a", "b")), f2=factor(c("b", "a")) ) m1 <- melt(df, 1, factorsAsStrings=TRUE) expect_identical( class(m1$value), "character" ) m2 <- melt(df, 1, factorsAsStrings=FALSE) expect_identical( class(m2$value), "factor" ) ## make sure we have faithfully reproduced an R factor expect_identical( m2$value, factor(c("a", "b", "b", "a")) ) ## factors with different levels -> convert to character to be safe df <- data.frame( id=1:2, f1=factor(c("a", "b")), f2=factor(c("c", "d")) ) expect_warning(melt(df, 1)) expect_warning( expect_warning( m <- melt(df, 1, factorsAsStrings = FALSE), "cannot avoid coercion", fixed = TRUE ), "attributes are not identical across measure variables", fixed = TRUE ) expect_identical( class(m$value), "character" ) }) test_that("melt.data.frame behaves when there are no measure variables", { df <- data.frame(x='a', y='b', z='c') expect_message( expect_identical(df, melt(df)), "Using x, y, z as id variables", fixed = TRUE ) m <- melt(df, id.vars = "x", measure.vars = NULL) expect_identical(df["x"], m) }) test_that("melt.data.frame preserves OBJECT bit on e.g. POSIXct", { t.wide <- data.frame(product=letters[1:5], result=c(2, 4, 0, 0, 1), t1=as.POSIXct("2014-05-26") + seq(0, 10800, length.out=5), t2=as.POSIXct("2014-05-27") + seq(0, 10800, length.out=5), t3=as.POSIXct("2014-05-28") + seq(0, 10800, length.out=5)) t.long <- melt(t.wide, measure.vars=c("t1", "t2", "t3"), value.name="time") expect_true(is.object(t.long$time)) }) test_that("melt.data.frame allows for lists in the set of id variables", { df <- data.frame(x = 1:5) df$y <- list( data.frame(), new.env(), as.name("foo"), 1, as.POSIXct(Sys.Date()) ) df$za <- letters[1:5] df$zb <- letters[6:10] df$zc <- letters[11:15] result <- melt(df, id=1:2) expect_identical(result$y[1:5], df$y) }) test_that("melt.data.frame throws when encountering POSIXlt", { df <- data.frame( x = 1:5, y = 6:10 ) df$z <- as.POSIXlt(Sys.time()) expect_error(melt(df, measure.vars = c("x", "y"))) }) reshape2/tests/testthat/test-margins.r0000644000176200001440000000207715104637043017576 0ustar liggesusersvars <- list(c("a", "b", "c"), c("d", "e", "f")) test_that("margins expanded", { expect_identical(margins(vars, "c")[[2]], c("c")) expect_identical(margins(vars, "b")[[2]], c("b", "c")) expect_identical(margins(vars, "a")[[2]], c("a", "b", "c")) expect_identical(margins(vars, "f")[[2]], c("f")) expect_identical(margins(vars, "e")[[2]], c("e", "f")) expect_identical(margins(vars, "d")[[2]], c("d", "e", "f")) }) test_that("margins intersect", { expect_identical(margins(vars, c("c", "f"))[-1], list("c", "f", c("c", "f"))) }) test_that("(all) comes after NA", { df <- data.frame(a = c("a", "b", NA), b = c("a", "b", NA), value = 1) df2 <- add_margins(df, "a") expect_identical(levels(df2$a), c("a", "b", NA, "(all)")) df3 <- add_margins(df, c("a", "b")) expect_identical(levels(df3$a), c("a", "b", NA, "(all)")) expect_identical(levels(df3$b), c("a", "b", NA, "(all)")) dc <- dcast(df, a ~ ., margins = TRUE, fun = length) expect_identical(levels(dc$a), c("a", "b", NA, "(all)")) expect_identical(as.character(dc$a), c("a", "b", NA, "(all)")) }) reshape2/tests/testthat/test-helper-colsplit.r0000644000176200001440000000232015104637043021233 0ustar liggesuserstest_that("colsplit works", { x <- c("a_1", "a_2", "b_2", "c_3") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", "c"), time = c(1L, 2L, 2L, 3L)) ) x <- c("a_1", "a_2", "b_2", "c_") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", "c"), time = c(1L, 2L, 2L, NA)) ) x <- c("a_1", "a_2", "b_2", "c") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", "c"), time = c(1L, 2L, 2L, NA)) ) x <- c("a", "a", "b", "c") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", "c"), time = NA) ) x <- c("a_1", "a_2", "b_2", NA) expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", NA), time = c(1L, 2L, 2L, NA)) ) x <- c("a_1", "a_2", "b_2", "c_3_4") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c("a", "a", "b", "c"), time = c("1", "2", "2", "3_4")) ) x <- c("TRUE_1", "TRUE_2", "TRUE_2", "FALSE_3") expect_identical( colsplit(x, "_", c("trt", "time")), data.frame(trt = c(TRUE, TRUE, TRUE, FALSE), time = c(1L, 2L, 2L, 3L)) ) }) reshape2/tests/testthat/test-cast.r0000644000176200001440000001620015104637043017061 0ustar liggesuserss2 <- array(seq.int(3 * 4), c(3,4)) s2m <- melt(s2) colnames(s2m) <- c("X1", "X2", "value") s3 <- array(seq.int(3 * 4 * 5), c(3,4,5)) s3m <- melt(s3) colnames(s3m) <- c("X1", "X2", "X3", "value") test_that("reshaping matches t and aperm", { # 2d expect_identical(s2, acast(s2m, X1 ~ X2), ignore_attr = "dimnames") expect_identical(t(s2), acast(s2m, X2 ~ X1), ignore_attr = "dimnames") expect_identical(as.vector(s2), as.vector(acast(s2m, X2 + X1 ~ .))) # 3d expect_identical(s3, acast(s3m, X1 ~ X2 ~ X3), ignore_attr = "dimnames") expect_identical(as.vector(s3), as.vector(acast(s3m, X3 + X2 + X1 ~ .))) expect_identical(aperm(s3, c(1,3,2)), acast(s3m, X1 ~ X3 ~ X2), ignore_attr = "dimnames") expect_identical(aperm(s3, c(2,1,3)), acast(s3m, X2 ~ X1 ~ X3), ignore_attr = "dimnames") expect_identical(aperm(s3, c(2,3,1)), acast(s3m, X2 ~ X3 ~ X1), ignore_attr = "dimnames") expect_identical(aperm(s3, c(3,1,2)), acast(s3m, X3 ~ X1 ~ X2), ignore_attr = "dimnames") expect_identical(aperm(s3, c(3,2,1)), acast(s3m, X3 ~ X2 ~ X1), ignore_attr = "dimnames") }) test_that("aggregation matches apply", { # 2d -> 1d expect_identical(colMeans(s2), as.vector(acast(s2m, X2 ~ ., mean))) expect_identical(rowMeans(s2), as.vector(acast(s2m, X1 ~ ., mean))) # 3d -> 1d expect_identical(apply(s3, 1, mean), as.vector(acast(s3m, X1 ~ ., mean))) expect_identical(apply(s3, 1, mean), as.vector(acast(s3m, . ~ X1, mean))) expect_identical(apply(s3, 2, mean), as.vector(acast(s3m, X2 ~ ., mean))) expect_identical(apply(s3, 3, mean), as.vector(acast(s3m, X3 ~ ., mean))) # 3d -> 2d expect_identical(apply(s3, c(1,2), mean), acast(s3m, X1 ~ X2, mean), ignore_attr = "dimnames") expect_identical(apply(s3, c(1,3), mean), acast(s3m, X1 ~ X3, mean), ignore_attr = "dimnames") expect_identical(apply(s3, c(2,3), mean), acast(s3m, X2 ~ X3, mean), ignore_attr = "dimnames") }) names(ChickWeight) <- tolower(names(ChickWeight)) chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE) test_that("aggregation matches table", { tab <- unclass(with(chick_m, table(chick, time))) cst <- acast(chick_m, chick ~ time, length) expect_identical(tab, cst, ignore_attr = "names") }) test_that("grand margins are computed correctly", { col <- acast(s2m, X1 ~ X2, mean, margins = "X1")[4, ] row <- acast(s2m, X1 ~ X2, mean, margins = "X2")[, 5] grand <- acast(s2m, X1 ~ X2, mean, margins = TRUE)[4, 5] expect_identical(col, colMeans(s2), ignore_attr = "names") expect_identical(row, rowMeans(s2), ignore_attr = "names") expect_identical(grand, mean(s2)) }) # test_that("internal margins are computed correctly", { cast <- dcast(chick_m, diet + chick ~ time, length, margins="diet") marg <- subset(cast, diet == "(all)")[-(1:2)] expect_identical( as.vector(as.matrix(marg)), as.vector(acast(chick_m, time ~ ., length)) ) joint <- subset(cast, diet != "(all)") joint$diet <- factor(joint$diet, levels = setdiff(levels(joint$diet), "(all)")) joint$chick <- factor(joint$chick, levels = setdiff(levels(joint$chick), "(all)")) expect_identical(joint, dcast(chick_m, diet + chick ~ time, length)) }) test_that("missing combinations filled correctly", { s2am <- subset(s2m, !(X1 == 1 & X2 == 1)) expect_equal(acast(s2am, X1 ~ X2)[1, 1], NA_integer_) expect_equal(acast(s2am, X1 ~ X2, length)[1, 1], 0) expect_equal(acast(s2am, X1 ~ X2, length, fill = 1)[1, 1], 1) }) test_that("drop = FALSE generates all combinations", { df <- data.frame(x = c("a", "b"), y = c("a", "b"), value = 1:2) expect_identical( as.vector(acast(df, x + y ~ ., drop = FALSE)), as.vector(acast(df, x ~ y)) ) }) test_that("aggregated values computed correctly", { ffm <- melt(french_fries, id = 1:4) count_c <- function(vars) as.table(acast(ffm, as.list(vars), length)) count_t <- function(vars) table(ffm[vars], useNA = "ifany") combs <- data.frame(combn(names(ffm)[1:5], 2L)) for (vars in combs) { expect_identical( count_c(vars), count_t(vars), label = toString(vars), ignore_attr = "names" ) } }) test_that("value.var overrides value col", { df <- data.frame( id1 = rep(letters[1:2],2), id2 = rep(LETTERS[1:2],each=2), var1=1:4) expect_message({ df.m <- melt(df) }, "Using id1, id2 as id variables", fixed = TRUE) df.m$value2 <- df.m$value * 2 expect_identical(acast(df.m, id2 + id1 ~ ., value.var="value")[, 1], 1:4, ignore_attr = "names") expect_identical(acast(df.m, id2 + id1 ~ ., value.var="value2")[, 1], 2 * 1:4, ignore_attr = "names") }) test_that("labels are correct when missing combinations dropped/kept", { df <- data.frame(fac1 = letters[1:4], fac2 = LETTERS[1:4], x = 1:4, stringsAsFactors = TRUE) mx <- melt(df, id = c("fac1", "fac2"), measure.var = "x") c1 <- dcast(mx[1:2, ], fac1 + fac2 ~ variable, length, drop = F) expect_identical(nrow(c1), 16L) c2 <- dcast(droplevels(mx[1:2, ]), fac1 + fac2 ~ variable, length, drop = F) expect_identical(nrow(c2), 4L) c3 <- dcast(mx[1:2, ], fac1 + fac2 ~ variable, length, drop = T) expect_identical(nrow(c3), 2L) }) test_that("factor value columns are handled", { df <- data.frame(fac1 = letters[1:4], fac2 = LETTERS[1:4], x = factor(1:4)) mx <- melt(df, id = c("fac1", "fac2"), measure.var = "x") c1 <- dcast(mx, fac1 + fac2 ~ variable) expect_identical(nrow(c1), 4L) expect_identical(ncol(c1), 3L) expect_type(c1$x, "character") c2 <- dcast(mx, fac1 ~ fac2 + variable) expect_identical(nrow(c2), 4L) expect_identical(ncol(c2), 5L) expect_type(c2$A_x, "character") expect_type(c2$B_x, "character") expect_type(c2$C_x, "character") expect_type(c2$D_x, "character") c3 <- acast(mx, fac1 + fac2 ~ variable) expect_identical(nrow(c3), 4L) expect_identical(ncol(c3), 1L) expect_true(is.character(c3)) c4 <- acast(mx, fac1 ~ fac2 + variable) expect_identical(nrow(c4), 4L) expect_identical(ncol(c4), 4L) expect_true(is.character(c4)) }) test_that("dcast evaluated in correct argument", { g <- c("a", "b") expr <- quote({ df <- data.frame(x = letters[1:2], y = letters[1:3], z = rnorm(6)) g <- c('b', 'a') dcast(df, y ~ ordered(x, levels = g)) }) expect_message( expect_named(eval(expr, envir = new.env()), c("y", "b", "a")), "Using z as value column", fixed = TRUE ) }) test_that(". ~ . returns single value", { one <- acast(s2m, . ~ ., sum) expect_equal(as.vector(one), 78) expect_equal(dimnames(one), list(".", ".")) }) test_that("drop = TRUE retains NA values", { df <- data.frame(x = 1:5, y = c(letters[1:4], NA), value = 5:1) out <- dcast(df, x + y ~ .) expect_equal(dim(out), c(5, 3)) expect_equal(out$., 5:1) }) test_that("useful error message if you use value_var", { expect_error(dcast(mtcars, vs ~ am, value_var = "cyl"), "Please use value.var", fixed = TRUE) expect_message( expect_equal(dim(dcast(mtcars, vs ~ am, value.var = "cyl")), c(2, 3)), "Aggregation function missing", fixed = TRUE ) }) test_that("useful error message if value.var doesn't exist", { expect_error(dcast(airquality, month ~ day, value.var = "test"), "value.var (test) not found in input", fixed = TRUE) }) reshape2/tests/testthat.R0000644000176200001440000000061415104637043015114 0ustar liggesusers# This file is part of the standard setup for testthat. # It is recommended that you do not modify it. # # Where should you do additional test configuration? # Learn more about the roles of various files in: # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview # * https://testthat.r-lib.org/articles/special-files.html library(testthat) library(reshape2) test_check("reshape2") reshape2/MD50000644000176200001440000000433015105023433012267 0ustar liggesusers8080a4f03fe45f7b9acbdbb9f51b3f6c *DESCRIPTION 581827da3959cce1750fb90f1eb98ec8 *LICENSE e9c12e0388ef428037ec2f359430812c *NAMESPACE 467eaac1f3b5d022195e06c4da362b7f *NEWS.md 75a292b159c02713caa9074a6020663a *R/RcppExports.R 9277c8a4eabfd400bfb829a769272590 *R/cast.r 125db94629ec768bc540371316d2eb80 *R/data.r dc3d99d161a35f5e1a8d723d865ecaf7 *R/formula.r be60b82da1500a97b295ec2eedcbcecd *R/helper-colsplit.r b88bd2b7d2e7ee40cefcf33e6b5145ab *R/helper-guess-value.r 5a4c0b8d627b9c0307c67012ce51e6e2 *R/helper-margins.r 2ba3f5c2b03f009ef33097ab006e1cfd *R/melt.r 3b203639e96d72299d6dc7ea6e97a179 *R/recast.r 703f0e7f087a046299646b6519cd9ded *R/reshape.r 2eb44aae9ad8d328afda7379086ec877 *R/utils.r 0a772926db293d997b9beaf17c046285 *README.md 11d6f343f97ca34edc7cb5ad4a174d05 *data/french_fries.rda 931bb9da3bce71ebcb25ba53c5dcd1e5 *data/smiths.rda 6a3f0a74f813cd68547e665f42b8a3cb *data/tips.rda b8d97bd0c37fd9d0b02ade4a429bb59e *inst/CITATION c04279b1fa261a1836d61377997b897a *man/add_margins.Rd 44424abff68208933f609fc34ec25de5 *man/cast.Rd d7858f9ddfb88fad7f49d4bdca7f7399 *man/colsplit.Rd 0e00c4cc241af45f1204f3bbd1f554ea *man/french_fries.Rd 3429b8bec5ae06d4244342cf2bbea272 *man/guess_value.Rd 3d35e9af2dbc20ae0a3eaa7ca0572ccd *man/margins.Rd d6f2f4a84a074f2dfdcd4e657dc82f62 *man/melt.Rd 407a4e0b78f9dd699104beaf8683563a *man/melt.array.Rd 175650903f4598177b6492eb788103c1 *man/melt.data.frame.Rd ddc992f9eba0069d43ed52257f9a1478 *man/melt.default.Rd ad825331c5a60b06c14296dcde34b067 *man/melt.list.Rd 06a1a5d8c52c5c58d5e76039100af4a2 *man/melt_check.Rd cd76f45422652e41d176fa7eccd55442 *man/parse_formula.Rd 790574147a29c7f0679fba4fec3d4c3b *man/recast.Rd a31c832e268f2a4e4c50bcadfa249833 *man/smiths.Rd 2052287fe0bdb2e4acc176273a36c5f7 *man/tips.Rd 2dbab2cfefc21e9c3d9b44d60b2cc771 *po/R-ko.po 15d543bb8dc1c303c8f4a9f54ef767ef *po/R-reshape.pot b399a76de0c24231603fb285107c9a71 *src/RcppExports.cpp 218543e36e9d04b9d40d13273bae0805 *src/melt.cpp 528cf5ffcb958a3504804592c299d943 *tests/testthat.R 3bc3ab8d5604dfdf795cac864bac26e6 *tests/testthat/test-cast.r c669c18da5c9c5a48a1f0f91b97f9c29 *tests/testthat/test-helper-colsplit.r ec9763b25438e5af70c5f34a5ae9b3c7 *tests/testthat/test-margins.r 2d5b5bf57cfe9686c6e49665b7660efe *tests/testthat/test-melt.r reshape2/po/0000755000176200001440000000000015104366121012400 5ustar liggesusersreshape2/po/R-reshape.pot0000644000176200001440000000150715104366121014755 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: R 2.15.1\n" "Report-Msgid-Bugs-To: bugs@r-project.org\n" "POT-Creation-Date: 2013-03-29 14:45\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "Aggregation function missing: defaulting to length" msgstr "" msgid "Dataframes have at most two output dimensions" msgstr "" msgid "Don't know how to parse" msgstr "" msgid "Using" msgstr "" msgid "as value column: use value.var to override." msgstr "" msgid "id variables not found in data:" msgstr "" msgid "measure variables not found in data:" msgstr "" msgid "," msgstr "" msgid "as id variables" msgstr "" msgid "Use var, not vars" msgstr "" reshape2/po/R-ko.po0000644000176200001440000000324315104366121013552 0ustar liggesusers# Korean translation for R reshape package # /po/R-ko.po # This file is distributed under the same license as the R reshape package. # R Development Translation Team - Korean # Chel Hee Lee , 2013. # Chel Hee Lee , 2013. # msgid "" msgstr "" "Project-Id-Version: reshape 1.2.2\n" "Report-Msgid-Bugs-To: bugs@r-project.org\n" "POT-Creation-Date: 2013-03-29 14:37\n" "PO-Revision-Date: 2013-04-01 17:44+0900\n" "Last-Translator: Eugene Jung \n" "Language-Team: R Development Translation Teams (Korean) \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Poedit-SourceCharset: utf-8\n" "X-Generator: Poedit 1.5.5\n" msgid "Aggregation function missing: defaulting to length" msgstr "결합 함수 누락: 기본 길이로 설정됩니다." msgid "Dataframes have at most two output dimensions" msgstr "데이터프레임(dataframes)은 대부분 두 개의 출력 차원을 가집니다." msgid "Don't know how to parse" msgstr "어떻게 parse할지 알 수 없습니다." msgid "Using" msgstr "사용" msgid "as value column: use value.var to override." msgstr "값 열로: 덮어쓰기 위해 value.var을 사용합니다." msgid "id variables not found in data:" msgstr "데이터에서 id 변수를 찾을 수 없습니다:" msgid "measure variables not found in data:" msgstr "데이터에서 측정 변수를 찾을 수 없습니다:" msgid "," msgstr "," msgid "as id variables" msgstr "id 변수처럼" msgid "Use var, not vars" msgstr "vars가 아닌 var를 사용하십시오." reshape2/R/0000755000176200001440000000000015104637331012167 5ustar liggesusersreshape2/R/RcppExports.R0000644000176200001440000000061115104637114014600 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 melt_dataframe <- function(data, id_ind, measure_ind, variable_name, value_name, factorsAsStrings, valueAsFactor) { .Call('_reshape2_melt_dataframe', PACKAGE = 'reshape2', data, id_ind, measure_ind, variable_name, value_name, factorsAsStrings, valueAsFactor) } reshape2/R/helper-margins.r0000644000176200001440000000511415104637043015270 0ustar liggesusers#' Figure out margining variables. #' #' Given the variables that form the rows and columns, and a set of desired #' margins, works out which ones are possible. Variables that can't be #' margined over are dropped silently. #' #' @param vars a list of character vectors giving the variables in each #' dimension #' @param margins a character vector of variable names to compute margins for. #' \code{TRUE} will compute all possible margins. #' @keywords manip internal #' @return list of margining combinations, or \code{NULL} if none. These are #' the combinations of variables that should have their values set to #' \code{(all)} margins <- function(vars, margins = NULL) { if (is.null(margins) || identical(margins, FALSE)) return(NULL) all_vars <- unlist(vars) if (isTRUE(margins)) { margins <- all_vars } # Start by grouping margins by dimension dims <- lapply(vars, intersect, margins) # Next, ensure high-level margins include lower-levels dims <- mapply(function(vars, margin) { lapply(margin, downto, vars) }, vars, dims, SIMPLIFY = FALSE, USE.NAMES = FALSE) # Finally, find intersections across all dimensions seq_0 <- function(x) c(0, seq_along(x)) indices <- expand.grid(lapply(dims, seq_0), KEEP.OUT.ATTRS = FALSE) # indices <- indices[rowSums(indices) > 0, ] lapply(seq_len(nrow(indices)), function(i){ unlist(mapply("[", dims, indices[i, ], SIMPLIFY = FALSE)) }) } upto <- function(a, b) { b[seq_len(match(a, b, nomatch = 0))] } downto <- function(a, b) { rev(upto(a, rev(b))) } #' Add margins to a data frame. #' #' Rownames are silently stripped. All margining variables will be converted #' to factors. #' #' @param df input data frame #' @param vars a list of character vectors giving the variables in each #' dimension #' @param margins a character vector of variable names to compute margins for. #' \code{TRUE} will compute all possible margins. #' @export add_margins <- function(df, vars, margins = TRUE) { margin_vars <- margins(vars, margins) # Return data frame if no margining necessary if (length(margin_vars) == 0) return(df) # Prepare data frame for addition of margins addAll <- function(x) { x <- addNA(x, TRUE) factor(x, levels = c(levels(x), "(all)"), exclude = NULL) } vars <- unique(unlist(margin_vars)) df[vars] <- lapply(df[vars], addAll) rownames(df) <- NULL # Loop through all combinations of margin variables, setting # those variables to (all) margin_dfs <- lapply(margin_vars, function(vars) { df[vars] <- rep(list(factor("(all)")), length(vars)) df }) rbind.fill(margin_dfs) } reshape2/R/data.r0000644000176200001440000000330615104366121013261 0ustar liggesusers#' Sensory data from a french fries experiment. #' #' This data was collected from a sensory experiment conducted at Iowa State #' University in 2004. The investigators were interested in the effect of #' using three different fryer oils had on the taste of the fries. #' #' Variables: #' #' \itemize{ #' \item time in weeks from start of study. #' \item treatment (type of oil), #' \item subject, #' \item replicate, #' \item potato-y flavour, #' \item buttery flavour, #' \item grassy flavour, #' \item rancid flavour, #' \item painty flavour #' } #' #' @docType data #' @format A data frame with 696 rows and 9 variables #' @keywords datasets "french_fries" #' Demo data describing the Smiths. #' #' A small demo dataset describing John and Mary Smith. Used in the #' introductory vignette. #' #' @docType data #' @format A data frame with 2 rows and 5 variables #' @keywords datasets "smiths" #' Tipping data #' #' #' One waiter recorded information about each tip he received over a #' period of a few months working in one restaurant. He collected several #' variables: #' #' \itemize{ #' \item tip in dollars, #' \item bill in dollars, #' \item sex of the bill payer, #' \item whether there were smokers in the party, #' \item day of the week, #' \item time of day, #' \item size of the party. #' } #' #' In all he recorded 244 tips. The data was reported in a collection of #' case studies for business statistics (Bryant & Smith 1995). #' #' @references Bryant, P. G. and Smith, M (1995) \emph{Practical Data #' Analysis: Case Studies in Business Statistics}. Homewood, IL: Richard D. #' Irwin Publishing: #' @format A data frame with 244 rows and 7 variables #' @keywords datasets "tips" reshape2/R/utils.r0000644000176200001440000000260615104637331013516 0ustar liggesusers"%||%" <- function(a, b) if (!is.null(a)) a else b all_identical <- function(xs) { if (length(xs) <= 1) return(TRUE) for (i in seq(2, length(xs))) { if (!identical(xs[[1]], xs[[i]])) return(FALSE) } TRUE } ## Get the attributes if common, NULL if not. normalize_melt_arguments <- function(data, measure.ind, factorsAsStrings) { measure.attributes <- lapply(measure.ind, function(i) { attributes(data[[i]]) }) ## Determine if all measure.attributes are equal measure.attrs.equal <- all_identical(measure.attributes) if (measure.attrs.equal) { measure.attributes <- measure.attributes[[1]] } else { warning("attributes are not identical across measure variables; ", "they will be dropped", call. = FALSE) measure.attributes <- NULL } if (!factorsAsStrings && !measure.attrs.equal) { warning("cannot avoid coercion of factors when measure attributes not identical", call. = FALSE) factorsAsStrings <- TRUE } ## If we are going to be coercing any factors to strings, we don't want to ## copy the attributes any.factors <- any( sapply( measure.ind, function(i) { is.factor( data[[i]] ) })) if (factorsAsStrings && any.factors) { measure.attributes <- NULL } list( measure.attributes = measure.attributes, factorsAsStrings = factorsAsStrings ) } is.string <- function(x) { is.character(x) && length(x) == 1 } reshape2/R/melt.r0000644000176200001440000002277515104637043013330 0ustar liggesusers#' Convert an object into a molten data frame. #' #' This the generic melt function. See the following functions #' for the details about different data structures: #' #' \itemize{ #' \item \code{\link{melt.data.frame}} for data.frames #' \item \code{\link{melt.array}} for arrays, matrices and tables #' \item \code{\link{melt.list}} for lists #' } #' #' @keywords manip #' @param data Data set to melt #' @param na.rm Should NA values be removed from the data set? This will #' convert explicit missings to implicit missings. #' @param ... further arguments passed to or from other methods. #' @param value.name name of variable used to store values #' @seealso \code{\link{cast}} #' @export melt <- function(data, ..., na.rm = FALSE, value.name = "value") { UseMethod("melt", data) } #' Melt a vector. #' For vectors, makes a column of a data frame #' #' @param data vector to melt #' @param na.rm Should NA values be removed from the data set? This will #' convert explicit missings to implicit missings. #' @param ... further arguments passed to or from other methods. #' @param value.name name of variable used to store values #' @keywords manip #' @seealso \code{\link{melt}}, \code{\link{cast}} #' @family melt methods #' @export melt.default <- function(data, ..., na.rm = FALSE, value.name = "value") { if (na.rm) data <- data[!is.na(data)] setNames(data.frame(data), value.name) } #' Melt a list by recursively melting each component. #' #' @keywords manip #' @param data list to recursively melt #' @param ... further arguments passed to or from other methods. #' @param level list level - used for creating labels #' @seealso \code{\link{cast}} #' @family melt methods #' @export #' @examples #' a <- as.list(c(1:4, NA)) #' melt(a) #' names(a) <- letters[1:4] #' melt(a) #' a <- list(matrix(1:4, ncol=2), matrix(1:6, ncol=2)) #' melt(a) #' a <- list(matrix(1:4, ncol=2), array(1:27, c(3,3,3))) #' melt(a) #' melt(list(1:5, matrix(1:4, ncol=2))) #' melt(list(list(1:3), 1, list(as.list(3:4), as.list(1:2)))) melt.list <- function(data, ..., level = 1) { parts <- lapply(data, melt, level = level + 1, ...) result <- rbind.fill(parts) # Add labels names <- names(data) %||% seq_along(data) lengths <- vapply(parts, nrow, integer(1)) labels <- rep(names, lengths) label_var <- attr(data, "varname") %||% paste("L", level, sep = "") result[[label_var]] <- labels # result <- cbind(labels, result) # result[, c(setdiff(names(result), "value"), "value")] result } #' Melt a data frame into form suitable for easy casting. #' #' You need to tell melt which of your variables are id variables, and which #' are measured variables. If you only supply one of \code{id.vars} and #' \code{measure.vars}, melt will assume the remainder of the variables in the #' data set belong to the other. If you supply neither, melt will assume #' factor and character variables are id variables, and all others are #' measured. #' #' @param data data frame to melt #' @param id.vars vector of id variables. Can be integer (variable position) #' or string (variable name). If blank, will use all non-measured variables. #' @param measure.vars vector of measured variables. Can be integer (variable #' position) or string (variable name)If blank, will use all non id.vars # variables. #' @param variable.name name of variable used to store measured variable names #' @param value.name name of variable used to store values #' @param na.rm Should NA values be removed from the data set? This will #' convert explicit missings to implicit missings. #' @param ... further arguments passed to or from other methods. #' @param factorsAsStrings Control whether factors are converted to character #' when melted as measure variables. When \code{FALSE}, coercion is forced if #' levels are not identical across the \code{measure.vars}. #' @family melt methods #' @keywords manip #' @seealso \code{\link{cast}} #' @export #' @examples #' names(airquality) <- tolower(names(airquality)) #' melt(airquality, id=c("month", "day")) #' names(ChickWeight) <- tolower(names(ChickWeight)) #' melt(ChickWeight, id=2:4) melt.data.frame <- function(data, id.vars, measure.vars, variable.name = "variable", ..., na.rm = FALSE, value.name = "value", factorsAsStrings = TRUE) { ## Get the names of id.vars, measure.vars vars <- melt_check(data, id.vars, measure.vars, variable.name, value.name) ## Match them to indices in the data id.ind <- match(vars$id, names(data)) measure.ind <- match(vars$measure, names(data)) ## Return early if we have id.ind but no measure.ind if (!length(measure.ind)) { return(data[id.vars]) } ## Get the attributes if common, NULL if not. args <- normalize_melt_arguments(data, measure.ind, factorsAsStrings) measure.attributes <- args$measure.attributes factorsAsStrings <- args$factorsAsStrings valueAsFactor <- "factor" %in% measure.attributes$class ## Heat to 2000 degrees celsius df <- melt_dataframe( data, as.integer(id.ind - 1L), as.integer(measure.ind - 1L), as.character(variable.name), as.character(value.name), as.logical(factorsAsStrings), as.logical(valueAsFactor) ) ## Ensure attributes set on value if available if (!is.null(measure.attributes)) attributes(df[[value.name]]) <- measure.attributes if (na.rm) { return(df[ !is.na(df[[value.name]]), ]) } else { return(df) } } #' Melt an array. #' #' This code is conceptually similar to \code{\link{as.data.frame.table}} #' #' @param data array to melt #' @param varnames variable names to use in molten data.frame #' @param ... further arguments passed to or from other methods. #' @param as.is if \code{FALSE}, the default, dimnames will be converted #' using \code{\link{type.convert}}. If \code{TRUE}, they will be left #' as strings. #' @param value.name name of variable used to store values #' @param na.rm Should NA values be removed from the data set? This will #' convert explicit missings to implicit missings. #' @keywords manip #' @export #' @seealso \code{\link{cast}} #' @family melt methods #' @examples #' a <- array(c(1:23, NA), c(2,3,4)) #' melt(a) #' melt(a, na.rm = TRUE) #' melt(a, varnames=c("X","Y","Z")) #' dimnames(a) <- lapply(dim(a), function(x) LETTERS[1:x]) #' melt(a) #' melt(a, varnames=c("X","Y","Z")) #' dimnames(a)[1] <- list(NULL) #' melt(a) melt.array <- function(data, varnames = names(dimnames(data)), ..., na.rm = FALSE, as.is = FALSE, value.name = "value") { var.convert <- function(x) { if (!is.character(x)) return(x) x <- type.convert(x, as.is = TRUE) if (!is.character(x)) return(x) factor(x, levels = unique(x)) } dn <- amv_dimnames(data) names(dn) <- varnames if (!as.is) { dn <- lapply(dn, var.convert) } labels <- expand.grid(dn, KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE) if (na.rm) { missing <- is.na(data) data <- data[!missing] labels <- labels[!missing, ] } value_df <- setNames(data.frame(as.vector(data)), value.name) cbind(labels, value_df) } #' @rdname melt.array #' @export melt.table <- melt.array #' @rdname melt.array #' @export melt.matrix <- melt.array #' Check that input variables to melt are appropriate. #' #' If id.vars or measure.vars are missing, \code{melt_check} will do its #' best to impute them. If you only supply one of id.vars and measure.vars, #' melt will assume the remainder of the variables in the data set belong to #' the other. If you supply neither, melt will assume discrete variables are #' id variables and all other are measured. #' #' @param data data frame #' @param id.vars vector of identifying variable names or indexes #' @param measure.vars vector of Measured variable names or indexes #' @param variable.name name of variable used to store measured variable names #' @param value.name name of variable used to store values #' @return a list giving id and measure variables names. melt_check <- function(data, id.vars, measure.vars, variable.name, value.name) { varnames <- names(data) # Convert positions to names if (!missing(id.vars) && is.numeric(id.vars)) { id.vars <- varnames[id.vars] } if (!missing(measure.vars) && is.numeric(measure.vars)) { measure.vars <- varnames[measure.vars] } # Check that variables exist if (!missing(id.vars)) { unknown <- setdiff(id.vars, varnames) if (length(unknown) > 0) { vars <- paste(unknown, collapse=", ") stop("id variables not found in data: ", vars, call. = FALSE) } } if (!missing(measure.vars)) { unknown <- setdiff(measure.vars, varnames) if (length(unknown) > 0) { vars <- paste(unknown, collapse=", ") stop("measure variables not found in data: ", vars, call. = FALSE) } } # Fill in missing pieces if (missing(id.vars) && missing(measure.vars)) { discrete <- vapply(data, function(x) is.character(x) || is.logical(x) || is.factor(x), logical(1L)) id.vars <- varnames[discrete] measure.vars <- varnames[!discrete] if (length(id.vars) != 0) { message("Using ", paste(id.vars, collapse = ", "), " as id variables") } else { message("No id variables; using all as measure variables") } } else if (missing(id.vars)) { id.vars <- setdiff(varnames, measure.vars) } else if (missing(measure.vars)) { measure.vars <- setdiff(varnames, id.vars) } # Ensure variable names are characters of length one if (!is.string(variable.name)) stop("'variable.name' should be a string", call. = FALSE) if (!is.string(value.name)) stop("'value.name' should be a string", call. = FALSE) list(id = id.vars, measure = measure.vars) } reshape2/R/helper-colsplit.r0000644000176200001440000000140615104366121015455 0ustar liggesusers#' Split a vector into multiple columns #' #' Useful for splitting variable names that a combination of multiple #' variables. Uses \code{\link{type.convert}} to convert each column to #' correct type, but will not convert character to factor. #' #' @param string character vector or factor to split up #' @param pattern regular expression to split on #' @param names names for output columns #' @keywords manip #' @export #' @examples #' x <- c("a_1", "a_2", "b_2", "c_3") #' vars <- colsplit(x, "_", c("trt", "time")) #' vars #' str(vars) colsplit <- function(string, pattern, names) { vars <- str_split_fixed(string, pattern, n = length(names)) df <- data.frame(alply(vars, 2, type.convert, as.is = TRUE), stringsAsFactors = FALSE) names(df) <- names df } reshape2/R/formula.r0000644000176200001440000000302615104637043014020 0ustar liggesusers#' Parse casting formulae. #' #' There are a two ways to specify a casting formula: either as a string, or #' a list of quoted variables. This function converts the former to the #' latter. #' #' Casting formulas separate dimensions with \code{~} and variables within #' a dimension with \code{+} or \code{*}. \code{.} can be used as a #' placeholder, and \code{...} represents all other variables not otherwise #' used. #' #' @param formula formula to parse #' @param varnames names of all variables in data #' @param value.var name of variable containing values #' @examples #' reshape2:::parse_formula("a + ...", letters[1:6]) #' reshape2:::parse_formula("a ~ b + d") #' reshape2:::parse_formula("a + b ~ c ~ .") parse_formula <- function(formula = "... ~ variable", varnames, value.var = "value") { remove.placeholder <- function(x) x[x != "."] replace.remainder <- function(x) { if (any(x == "...")) c(x[x != "..."], remainder) else x } if (inherits(formula, "formula")) { formula <- str_c(deparse(formula, 500), collapse = "") } if (is.character(formula)) { dims <- str_split(formula, fixed("~"))[[1]] formula <- lapply(str_split(dims, "[+*]"), str_trim) formula <- lapply(formula, remove.placeholder) all_vars <- unlist(formula) if (any(all_vars == "...")) { remainder <- setdiff(varnames, c(all_vars, value.var)) formula <- lapply(formula, replace.remainder) } } if (!is.list(formula)) { stop("Don't know how to parse", formula, call. = FALSE) } lapply(formula, as.quoted) } reshape2/R/helper-guess-value.r0000644000176200001440000000077115104366121016070 0ustar liggesusers#' Guess name of value column #' #' Strategy: #' \enumerate{ #' \item Is value or (all) column present? If so, use that #' \item Otherwise, guess that last column is the value column #' } #' #' @param df data frame to guess value column from #' @keywords internal guess_value <- function(df) { if ("value" %in% names(df)) return("value") if ("(all)" %in% names(df)) return("(all)") last <- names(df)[ncol(df)] message("Using ", last, " as value column: use value.var to override.") last } reshape2/R/reshape.r0000644000176200001440000000017415104637043014003 0ustar liggesusers##' @importFrom Rcpp evalCpp ##' @importFrom stats setNames ##' @importFrom utils type.convert ##' @useDynLib reshape2 NULL reshape2/R/cast.r0000644000176200001440000001727315104637043013316 0ustar liggesusers#' Cast functions #' Cast a molten data frame into an array or data frame. #' #' Use \code{acast} or \code{dcast} depending on whether you want #' vector/matrix/array output or data frame output. Data frames can have at #' most two dimensions. #' #' The cast formula has the following format: #' \code{x_variable + x_2 ~ y_variable + y_2 ~ z_variable ~ ... } #' The order of the variables makes a difference. The first varies slowest, #' and the last fastest. There are a couple of special variables: "..." #' represents all other variables not used in the formula and "." represents #' no variable, so you can do \code{formula = var1 ~ .}. #' #' Alternatively, you can supply a list of quoted expressions, in the form #' \code{list(.(x_variable, x_2), .(y_variable, y_2), .(z))}. The advantage #' of this form is that you can cast based on transformations of the #' variables: \code{list(.(a + b), (c = round(c)))}. See the documentation #' for \code{\link[plyr]{.}} for more details and alternative formats. #' #' If the combination of variables you supply does not uniquely identify one #' row in the original data set, you will need to supply an aggregating #' function, \code{fun.aggregate}. This function should take a vector of #' numbers and return a single summary statistic. #' #' @keywords manip #' @param data molten data frame, see \code{\link{melt}}. #' @param formula casting formula, see details for specifics. #' @param fun.aggregate aggregation function needed if variables do not #' identify a single observation for each output cell. Defaults to length #' (with a message) if needed but not specified. #' @param ... further arguments are passed to aggregating function #' @param margins vector of variable names to compute margins for, or TRUE #' to compute all margins. Any variables that can not be margined over #' will be silently dropped. #' @param subset quoted expression used to subset data prior to reshaping, #' e.g. \code{subset = .(variable=="length")}. #' @param fill value with which to fill in structural missings, defaults to #' value from applying \code{fun.aggregate} to 0 length vector #' @param drop should missing combinations dropped or kept? #' @param value.var name of column which stores values, see #' \code{\link{guess_value}} for default strategies to figure this out. #' @seealso \code{\link{melt}}, \url{http://had.co.nz/reshape/} #' @importFrom plyr alply amv_dimnames as.quoted eval.quoted id llply rbind.fill split_labels vaggregate #' @import stringr #' @examples #' #Air quality example #' names(airquality) <- tolower(names(airquality)) #' aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE) #' #' acast(aqm, day ~ month ~ variable) #' acast(aqm, month ~ variable, mean) #' acast(aqm, month ~ variable, mean, margins = TRUE) #' dcast(aqm, month ~ variable, mean, margins = c("month", "variable")) #' #' library(plyr) # needed to access . function #' acast(aqm, variable ~ month, mean, subset = .(variable == "ozone")) #' acast(aqm, variable ~ month, mean, subset = .(month == 5)) #' #' #Chick weight example #' names(ChickWeight) <- tolower(names(ChickWeight)) #' chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE) #' #' dcast(chick_m, time ~ variable, mean) # average effect of time #' dcast(chick_m, diet ~ variable, mean) # average effect of diet #' acast(chick_m, diet ~ time, mean) # average effect of diet & time #' #' # How many chicks at each time? - checking for balance #' acast(chick_m, time ~ diet, length) #' acast(chick_m, chick ~ time, mean) #' acast(chick_m, chick ~ time, mean, subset = .(time < 10 & chick < 20)) #' #' acast(chick_m, time ~ diet, length) #' #' dcast(chick_m, diet + chick ~ time) #' acast(chick_m, diet + chick ~ time) #' acast(chick_m, chick ~ time ~ diet) #' acast(chick_m, diet + chick ~ time, length, margins="diet") #' acast(chick_m, diet + chick ~ time, length, drop = FALSE) #' #' #Tips example #' dcast(melt(tips), sex ~ smoker, mean, subset = .(variable == "total_bill")) #' #' ff_d <- melt(french_fries, id=1:4, na.rm=TRUE) #' acast(ff_d, subject ~ time, length) #' acast(ff_d, subject ~ time, length, fill=0) #' dcast(ff_d, treatment ~ variable, mean, margins = TRUE) #' dcast(ff_d, treatment + subject ~ variable, mean, margins="treatment") #' if (require("lattice")) { #' lattice::xyplot(`1` ~ `2` | variable, dcast(ff_d, ... ~ rep), aspect="iso") #' } #' @name cast NULL cast <- function(data, formula, fun.aggregate = NULL, ..., subset = NULL, fill = NULL, drop = TRUE, value.var = guess_value(data), value_var) { if (!missing(value_var)) { stop("Please use value.var instead of value_var.", call. = FALSE) } if (!(value.var %in% names(data))) { stop("value.var (", value.var, ") not found in input", call. = FALSE) } if (!is.null(subset)) { include <- data.frame(eval.quoted(subset, data)) data <- data[rowSums(include) == ncol(include), ] } formula <- parse_formula(formula, names(data), value.var) value <- data[[value.var]] # Need to branch here depending on whether or not we have strings or # expressions - strings should avoid making copies of the data vars <- lapply(formula, eval.quoted, envir = data, enclos = parent.frame(2)) # Compute labels and id values ids <- lapply(vars, id, drop = drop) # Empty specifications (.) get repeated id is_empty <- vapply(ids, length, integer(1)) == 0 empty <- structure(rep(1, nrow(data)), n = 1L) ids[is_empty] <- rep(list(empty), sum(is_empty)) labels <- mapply(split_labels, vars, ids, MoreArgs = list(drop = drop), SIMPLIFY = FALSE, USE.NAMES = FALSE) labels[is_empty] <- rep(list(data.frame(. = ".")), sum(is_empty)) overall <- id(rev(ids), drop = FALSE) n <- attr(overall, "n") # Aggregate duplicates if (any(duplicated(overall)) || !is.null(fun.aggregate)) { if (is.null(fun.aggregate)) { message("Aggregation function missing: defaulting to length") fun.aggregate <- length } ordered <- vaggregate(.value = value, .group = overall, .fun = fun.aggregate, ..., .default = fill, .n = n) overall <- seq_len(n) } else { # Add in missing values, if necessary if (length(overall) < n) { overall <- match(seq_len(n), overall, nomatch = NA) } else { overall <- order(overall) } ordered <- value[overall] if (!is.null(fill)) { ordered[is.na(ordered)] <- fill } } ns <- vapply(ids, attr, double(1), "n") dim(ordered) <- ns list( data = ordered, labels = labels ) } #' @rdname cast #' @export dcast <- function(data, formula, fun.aggregate = NULL, ..., margins = NULL, subset = NULL, fill=NULL, drop = TRUE, value.var = guess_value(data)) { formula <- parse_formula(formula, names(data), value.var) if (length(formula) > 2) { stop("Dataframes have at most two output dimensions") } if (!is.null(margins)) { data <- add_margins(data, lapply(formula, names), margins) } res <- cast(data, formula, fun.aggregate, ..., subset = subset, fill = fill, drop = drop, value.var = value.var) data <- as.data.frame.matrix(res$data, stringsAsFactors = FALSE) names(data) <- array_names(res$labels[[2]]) stopifnot(nrow(res$labels[[1]]) == nrow(data)) cbind(res$labels[[1]], data) } #' @rdname cast #' @export acast <- function(data, formula, fun.aggregate = NULL, ..., margins = NULL, subset = NULL, fill=NULL, drop = TRUE, value.var = guess_value(data)) { formula <- parse_formula(formula, names(data), value.var) if (!is.null(margins)) { data <- add_margins(data, lapply(formula, names), margins) } res <- cast(data, formula, fun.aggregate, ..., subset = subset, fill = fill, drop = drop, value.var = value.var) dimnames(res$data) <- lapply(res$labels, array_names) res$data } array_names <- function(df) { do.call(paste, c(df, list(sep = "_"))) } reshape2/R/recast.r0000644000176200001440000000154715104366121013636 0ustar liggesusers#' Recast: melt and cast in a single step #' #' This conveniently wraps melting and (d)casting a data frame into #' a single step. #' #' @param data data set to melt #' @param formula casting formula, see \code{\link{dcast}} for specifics #' @param ... other arguments passed to \code{\link{dcast}} #' @param id.var identifying variables. If blank, will use all non #' measure.var variables #' @param measure.var measured variables. If blank, will use all non #' id.var variables #' @keywords manip #' @seealso \url{http://had.co.nz/reshape/} #' @export #' @examples #' recast(french_fries, time ~ variable, id.var = 1:4) recast <- function(data, formula, ..., id.var, measure.var) { if (any(c("id.vars", "measure.vars") %in% names(match.call()))) { stop("Use var, not vars\n") } molten <- melt(data, id.var, measure.var) dcast(molten, formula, ...) } reshape2/data/0000755000176200001440000000000011440164053012672 5ustar liggesusersreshape2/data/tips.rda0000644000176200001440000000504412057435674014363 0ustar liggesusersݚoh]g¦mZWX풦I&69YVe6p\ƥIMRA"7n/ Ad"|DͶ{~ޛ4cN9y=7>28/rBZTSv+ss{k]koV޼+t+y/ϥc_y}Swe=_h%-L+eǹE\זMOg.`-p_MS˵S>È3yƈ5Tq~(q;sA~=p+lW8`}f?ca̗Kl{YA Giik:7?x9[3lokOם>CWv~` 3x uyc/n}ޟ&y<ž=vaN $\'Cw|A^帏B&_chWsb_=< a_?}5x;Os\DC>8#8Ãw1;Α[kO|O#ϱ؅]Aa[A8C;>:T+3S߹q9^SA}שd eĽ']grn~qKn.Y8;gUԃ^Ĺ w Gv~r؃,q">ĥON`O?OP‘u;3Ů}&7QWu~Ս{vv#.E֡5rΓۍcrMĻvx77ޔrЋ~~2u~H1ޏn_6oF>Uًv qv>u uzLVqN>S vnd(mϑyӱC4}*~/,~-u*-y=coֿ1y^Y8[Ռ~ȷwش4eYk7׊ĨUΛ堝lM+?NFvͬZfk^X;3{:?Qk :WeY^[Y\ng|*VѬiU5e{qunfǨ}v=սfn\F(|b<(VPk'RzTƵclǾUMdލw#wuAvҜth.\^ڒlowõNowus|jsznaav //ЎHD$f!V mtջ>͞~)e1s3Ilݤ?Mf,_:ʮlpY>7Ү nq]^k&;?M7ٻUmg_ g,,T?y)]v._\|Jd+V.sW{t/-~yl=&t\xH'N$Sў=Ҟ=O{ڋ R)A e2H R)U W2\ep*U O2«yݕ h収?zc?c;8~惏o}N+m[__?R?K,R?K,cc'>ty~x?z+E,t2A^px!'⻬Ye/_Z{ZzD?FNY R? 7_-nqTR٭a|C|٣Ǘ2L/2L/2L/2L/2L/2H"{{Z\܏/Ͽݼ_~'oR_4.F>8CrWsl\F^ryitw~(w-XGK9ވD7i?ҧz1\\"_jG_"ވzE4'?C8Џ [ 2)x%Y\O}RJ_4.G{~ߥzZ;i-rkqq}9厡F?gWZ\^4CIQy7Gv>~MWEyx&?W~>G>pR q}5O&Sp4.\c\~}Dя+@Ips% W+F=ػ oE(wD~p=%Ww!z?DOgqPo _Ni:8^|=CwW*# }?1/#WG81iWЧ%?'hȳu%vG/6̯oowI<~[ /E?w?~3,I~||'G瓾b_3ɟI//E? ;߯sbݳ-b}LUOy?7۟1>wv>, d'-<}Ob/ce~ KQp#O^>ᑘOp3˸OX\3Obw/#㌞X¯">QN~Og7Ɠy xI)_roZD~pz$a]߸߰lxS<^ZME~w'f~5~o6H/6qwCW5ޯ$}/[ד}iט4?ߎr!I  ^S/ ~Th3~3ƉQkh|NJd"'|"}a.x1߇}xx`ޔ>΄w"%3_E9%<*i><>t4;Ǖ86cqYh ~f5w3zX灗8G pql\^r ~kwio* Nx^X O*8_W?_ dډtCq3yu!;îT/|)˒?nNsOi4gȏ}'}k}AKi}1pj<3ߙg3`W8I>r+`,L{~79i,۳C5e< JC*}ߏqW~O`suljIsIwbǒB;&_Kwq?&4~oOiC~o"):?Ƀ%k^Kŭ<(y#h4~LZ?f;d=?Ӿ~vIX9óӷ+yq?~=+^P|qn-xWbٗ /vϵ^uat"Јw*~|ӢͯWsSIoƼ[8 xg8qC^Z\<~W3}`^&'/WM3 f.n~X^oڭG>S~_%8Oy_ӳ ވE{q{cG<?ܓk~(] qKqǬͧSg\DԃmEOuEM}dkB)я ?M +n~҄RtweA9Q:xM?=ˏ[ci9CTSv[s8radדq"p_7?\,-ɸ_MSY/s/^^x957 F|V~A^8.on_8Pڧc!_WszU:kMC~}Y8j8i}OOz8_gjxaOߖa_a&0'71N?i}~/co,K,lᾺH8x|z^SssO{'yj 釕z' Uyi+q'̍'EIGI [w8nKwG)\Pwߪ|Wٯ`>b^1^o9S?su!7Lr_O`~_ܥ'G+7y>lbŞ@ɏIq@Ϋ}O_Ccpy!~Gw7KXi\9WB1@O87qu'kB%9yN|ySrwmJxu.x.=ΎCzy״jSMbn2~Ǿ\Zsw9k+~styQߟXǩƸH?/ri I9Pcٙ+ U^I|>OzLByey|#u>ʽ5{9s I}wp^u-7{GҼ}D3z;vq~NҰ ) >*qxHS"ުyyijy0cW[qXC'R{/jGx?g<'˼gS.~V>͘g_%?Nc=j̛1˂_'5K%1s ύz/@9?YtD|˯|7L_-ޓr3Ngh7r9r<;*4o Wi^{: ߌ)];X|^Tz}9!Dyx\*X;3%~ϸ^®S}ȏ~hOnH:'ZQ Ir7h51JXg·$y v/~/' 08>Hۓ|N?9˫T9JS53~a8;~Ls~fUq=5=Yy'_cnqHzxUĿWr׬ W>|]N`?OWw*}aϹ}齂'|` .T{q?12o}K5{ĉny3?O\=}7p_u~OCտJd4|KVQ<ߓ Ƽki=/ OvOD ycs1I>s<67T?Lg{g/S#{ɕ3{<ݏ>M۷~rӻqɣwn:\gwo|ݻέ?WέO?W*xO6vgBGgpd௦׽FkuoS:=ljiuO`P-$TK+ 6UK+ 6UK+ 6UK+ :[QV5qEM{~\Q{~\Q{~\Q{ujӯno]$o]UKv7TKvUKg΀Q-Z:IШN4[rtUo 6}SomjM r{7%v㛒sMjMȶ{d vl"s]unNgu>ٴ MkXڴ -khڲ -kxr -qfmlZضmܺEjBkRlbwlrwlCѹujq:WnqDG^]+ٻz!{w]&͆ b﮻)b﮻Ib﮻ib﮻9omo C+ VXZ VK^ Rl lBb, ы(DX8pg7pg7pg7pLӹjz7QpM& D6(wŸᾀX֪p֪64U8Ck73} qLAM qSPS؛))f j {35Yc5Yc5Yc5Yc5Yc5Yc5Yc5Yc5Yc5Yc5Yc5YS̼Tli *64oJu杦bNSPy);m9N[@μ3Lmao&ݶ7n[؛I-ͤfm {3鶶֤Znk{kM5鶶֤ZO­$ZO­$ZO­$ZO­$ZO­$ZO­$Zok{kͿ5Zok{kͿ5}{7l{kmdm9Y[@Fu̿]9oW@3v̿]9oW@3v̿]9oW@3v̿]9oW@3v̿]9oW@3v̿]9oW@3v̿5vۙ[ogmͿ5v۵7og ștr&ݮI+ g ștr&ݮI+ g ștr&ݮI+ g ștr&ݮI+ g ștr&ݮI+ g ștr&ݮI+ g ștr&ݮI+ g̿3vۙ{ogͿ7v~M^C7\o ޤwE۾&L!כt{C7\o ޤrI7zno&ސM!כt{C7\o ޤrI7zno&ސM!כt{C7L}9n_@Τ3̿7ۛ{ooͿ7owÛEw(`o ؛t&ݡIw(`o ؛t&ݡIw(`o ؛t&ݡIw(`o ؛t&ݡIw(`o ؛t&ݡIw(`o ؛tBͰLa?t~0` ;wh?7`Xlo>`{Lm0?`{Lm0LCaz&0=P(L?g 3LCaz&0=P(L?g 3LCaz&=ܜ=_ݺ{޹hJreshape2/data/smiths.rda0000644000176200001440000000037312057435674014713 0ustar liggesusers r0b```b`b@& `d`lŹ% @P 3/X5XFUZT USM,X 3--1$a>?HEp0_|ccu.ۂ%KM9 Ҥ($37fNL1S33`2<9`VrA2G ĒDDP>breshape2/src/0000755000176200001440000000000015104642153012553 5ustar liggesusersreshape2/src/melt.cpp0000644000176200001440000002400515104637043014223 0ustar liggesusers#include using namespace Rcpp; // A debug macro -- change to 'debug(x) x' for debug output #define debug(x) // An optimized rep #define DO_REP_ATOMIC(RTYPE, CTYPE, ACCESSOR) \ { \ Shield output(Rf_allocVector(RTYPE, nout)); \ for (int i = 0; i < n; ++i) { \ memcpy((char*)ACCESSOR(output) + i * xn * sizeof(CTYPE), \ (char*)ACCESSOR(x), \ sizeof(CTYPE) * xn); \ } \ return output; \ } \ #define DO_REP_NONATOMIC(RTYPE, SET, GET) \ { \ int counter = 0; \ Shield output(Rf_allocVector(RTYPE, nout)); \ for (int i = 0; i < n; ++i) { \ for (int j = 0; j < xn; ++j) { \ SET(output, counter++, GET(x, j)); \ } \ } \ return output; \ } SEXP rep_(SEXP x, int n) { int xn = Rf_length(x); int nout = xn * n; switch (TYPEOF(x)) { // Atomic types case INTSXP: DO_REP_ATOMIC(INTSXP, int, INTEGER); case REALSXP: DO_REP_ATOMIC(REALSXP, double, REAL); case LGLSXP: DO_REP_ATOMIC(LGLSXP, int, LOGICAL); case CPLXSXP: DO_REP_ATOMIC(CPLXSXP, Rcomplex, COMPLEX); case RAWSXP: DO_REP_ATOMIC(RAWSXP, Rbyte, RAW); // Non-atomic types case STRSXP: DO_REP_NONATOMIC(STRSXP, SET_STRING_ELT, STRING_ELT); case VECSXP: DO_REP_NONATOMIC(VECSXP, SET_VECTOR_ELT, VECTOR_ELT); // Unsupported types default: { stop("Unhandled RTYPE"); return R_NilValue; } } } // An optimized rep_each #define DO_REP_EACH_ATOMIC(RTYPE, CTYPE, ACCESSOR) \ { \ int counter = 0; \ Shield output(Rf_allocVector(RTYPE, nout)); \ CTYPE* x_ptr = ACCESSOR(x); \ CTYPE* output_ptr = ACCESSOR(output); \ for (int i = 0; i < xn; ++i) { \ for (int j = 0; j < n; ++j) { \ output_ptr[counter++] = x_ptr[i]; \ } \ } \ return output; \ } #define DO_REP_EACH_NONATOMIC(RTYPE, SET, GET) \ { \ int counter = 0; \ Shield output(Rf_allocVector(RTYPE, nout)); \ for (int i = 0; i < xn; ++i) { \ for (int j = 0; j < n; ++j) { \ SET(output, counter++, GET(x, i)); \ } \ } \ return output; \ } SEXP rep_each_(SEXP x, int n) { int xn = Rf_length(x); int nout = xn * n; switch (TYPEOF(x)) { // Atomic types case INTSXP: DO_REP_EACH_ATOMIC(INTSXP, int, INTEGER); case REALSXP: DO_REP_EACH_ATOMIC(REALSXP, double, REAL); case LGLSXP: DO_REP_EACH_ATOMIC(LGLSXP, int, LOGICAL); case CPLXSXP: DO_REP_EACH_ATOMIC(CPLXSXP, Rcomplex, COMPLEX); case RAWSXP: DO_REP_EACH_ATOMIC(RAWSXP, Rbyte, RAW); // Non-atomic types case STRSXP: DO_REP_EACH_NONATOMIC(STRSXP, SET_STRING_ELT, STRING_ELT); case VECSXP: DO_REP_EACH_NONATOMIC(VECSXP, SET_VECTOR_ELT, VECTOR_ELT); // Unsupported types default: { stop("Unhandled RTYPE"); return R_NilValue; } } } // Optimized factor routine for the case where we want to make // a factor from a vector of names -- used for generating the // 'variable' column in the melted data.frame IntegerVector make_variable_column(CharacterVector x, int nrow) { IntegerVector fact = seq(1, x.size()); IntegerVector output = rep_each_(fact, nrow); output.attr("levels") = x; output.attr("class") = "factor"; return output; } // Ensure that we index in the column range of the data -- // just to double-check everything went okay upstream void check_indices(IntegerVector ind, int ncol, std::string msg) { int n = ind.size(); for (int i = 0; i < n; ++i) { if (ind[i] < 0) { stop(msg + "index less than zero"); } if (ind[i] >= ncol) { stop(msg + "index > number of columns"); } if (ind[i] == NA_INTEGER) { stop(msg + "no match found"); } } } // Concatenate vectors for the 'value' column #define DO_CONCATENATE(CTYPE) \ { \ memcpy((char*)dataptr(output) + i* nrow * sizeof(CTYPE), \ (char*)dataptr(tmp), \ nrow * sizeof(CTYPE)); \ break; \ } SEXP concatenate(const DataFrame& x, IntegerVector ind, bool factorsAsStrings) { int nrow = x.nrows(); int n_ind = ind.size(); // We coerce up to the 'max type' if necessary, using the fact // that R's SEXPTYPEs are also ordered in terms of 'precision' // Note: we convert factors to characters if necessary int max_type = 0; int ctype = 0; for (int i = 0; i < n_ind; ++i) { if (Rf_isFactor(x[ind[i]]) and factorsAsStrings) { ctype = STRSXP; } else { ctype = TYPEOF(x[ind[i]]); } max_type = ctype > max_type ? ctype : max_type; } debug(printf("Max type of value variables is %s\n", Rf_type2char(max_type))); Armor tmp; Shield output(Rf_allocVector(max_type, nrow * n_ind)); for (int i = 0; i < n_ind; ++i) { // a 'tmp' pointer to the current column being iterated over, or // a coerced version if necessary if (TYPEOF(x[ind[i]]) == max_type) { tmp = x[ind[i]]; } else if (Rf_isFactor(x[ind[i]]) and factorsAsStrings) { tmp = Rf_asCharacterFactor(x[ind[i]]); } else { tmp = Rf_coerceVector(x[ind[i]], max_type); } switch (max_type) { // Atomic types case INTSXP: DO_CONCATENATE(int); case REALSXP: DO_CONCATENATE(double); case LGLSXP: DO_CONCATENATE(int); case CPLXSXP: DO_CONCATENATE(Rcomplex); case RAWSXP: DO_CONCATENATE(Rbyte); // Non-atomic types case STRSXP: { for (int j = 0; j < nrow; ++j) { SET_STRING_ELT(output, i * nrow + j, STRING_ELT(tmp, j)); } break; } } } return output; } // [[Rcpp::export]] List melt_dataframe(const DataFrame& data, const IntegerVector& id_ind, const IntegerVector& measure_ind, String variable_name, String value_name, bool factorsAsStrings, bool valueAsFactor) { int nrow = data.nrows(); CharacterVector data_names = as(data.attr("names")); int n_id = id_ind.size(); debug(Rprintf("n_id == %i\n", n_id)); int n_measure = measure_ind.size(); debug(Rprintf("n_measure == %i\n", n_measure)); // Don't melt if the value variables are non-atomic for (int i = 0; i < n_measure; ++i) { if (!Rf_isVectorAtomic(data[measure_ind[i]])) { stop("Can't melt data.frames with non-atomic 'measure' columns"); } } // The output should be a data.frame with: // number of columns == number of id vars + 'variable' + 'value', // with number of rows == data.nrow() * number of value vars List output = no_init(n_id + 2); // First, allocate the ID variables // we repeat each ID vector n_measure times // A define to handle the different possible types #define REP(OBJECT, RTYPE) \ case RTYPE: { \ output[i] = rep_(OBJECT, n_measure); \ Rf_copyMostAttrib(OBJECT, output[i]); \ break; \ } for (int i = 0; i < n_id; ++i) { SEXP object = data[id_ind[i]]; if (Rf_inherits(object, "POSIXlt")) { std::string var = std::string(data_names[id_ind[i]]); Rcpp::stop("'%s' is a POSIXlt. Please convert to POSIXct.", var); } switch (TYPEOF(object)) { REP(object, LGLSXP); REP(object, INTSXP); REP(object, REALSXP); REP(object, STRSXP); REP(object, CPLXSXP); REP(object, RAWSXP); REP(object, VECSXP); default: { stop("internal error: unnhandled vector type in REP"); } } } // Now, we assign the 'variable' and 'value' columns // 'variable' is made up of repeating the names of the 'measure' variables, // each nrow times. We want this to be a factor as well. CharacterVector id_names = no_init(n_measure); for (int i = 0; i < n_measure; ++i) { id_names[i] = data_names[measure_ind[i]]; } output[n_id] = make_variable_column(id_names, nrow); // 'value' is made by concatenating each of the 'value' variables output[n_id + 1] = concatenate(data, measure_ind, factorsAsStrings); // Make the List more data.frame like // Set the row names output.attr("row.names") = IntegerVector::create(IntegerVector::get_na(), -(nrow * n_measure)); // Set the names CharacterVector out_names = no_init(n_id + 2); for (int i = 0; i < n_id; ++i) { out_names[i] = data_names[id_ind[i]]; } out_names[n_id] = variable_name; out_names[n_id + 1] = value_name; output.attr("names") = out_names; // Set the class output.attr("class") = "data.frame"; return output; } reshape2/src/RcppExports.cpp0000644000176200001440000000352015104637114015551 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; #ifdef RCPP_USE_GLOBAL_ROSTREAM Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif // melt_dataframe List melt_dataframe(const DataFrame& data, const IntegerVector& id_ind, const IntegerVector& measure_ind, String variable_name, String value_name, bool factorsAsStrings, bool valueAsFactor); RcppExport SEXP _reshape2_melt_dataframe(SEXP dataSEXP, SEXP id_indSEXP, SEXP measure_indSEXP, SEXP variable_nameSEXP, SEXP value_nameSEXP, SEXP factorsAsStringsSEXP, SEXP valueAsFactorSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const DataFrame& >::type data(dataSEXP); Rcpp::traits::input_parameter< const IntegerVector& >::type id_ind(id_indSEXP); Rcpp::traits::input_parameter< const IntegerVector& >::type measure_ind(measure_indSEXP); Rcpp::traits::input_parameter< String >::type variable_name(variable_nameSEXP); Rcpp::traits::input_parameter< String >::type value_name(value_nameSEXP); Rcpp::traits::input_parameter< bool >::type factorsAsStrings(factorsAsStringsSEXP); Rcpp::traits::input_parameter< bool >::type valueAsFactor(valueAsFactorSEXP); rcpp_result_gen = Rcpp::wrap(melt_dataframe(data, id_ind, measure_ind, variable_name, value_name, factorsAsStrings, valueAsFactor)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_reshape2_melt_dataframe", (DL_FUNC) &_reshape2_melt_dataframe, 7}, {NULL, NULL, 0} }; RcppExport void R_init_reshape2(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } reshape2/NAMESPACE0000644000176200001440000000116515104637043013210 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(melt,array) S3method(melt,data.frame) S3method(melt,default) S3method(melt,list) S3method(melt,matrix) S3method(melt,table) export(acast) export(add_margins) export(colsplit) export(dcast) export(melt) export(recast) import(stringr) importFrom(Rcpp,evalCpp) importFrom(plyr,alply) importFrom(plyr,amv_dimnames) importFrom(plyr,as.quoted) importFrom(plyr,eval.quoted) importFrom(plyr,id) importFrom(plyr,llply) importFrom(plyr,rbind.fill) importFrom(plyr,split_labels) importFrom(plyr,vaggregate) importFrom(stats,setNames) importFrom(utils,type.convert) useDynLib(reshape2) reshape2/LICENSE0000644000176200001440000000006115104637043012770 0ustar liggesusersYEAR: 2008-2016 COPYRIGHT HOLDER: Hadley Wickham reshape2/NEWS.md0000644000176200001440000000576415104642144013076 0ustar liggesusers# reshape2 1.4.5 * No longer uses non-API entry points (@kevinushey, #106). * Other various fixes for `R CMD check` issues. # reshape2 1.4.4 * Fix R CMD check failure in R-devel. # Version 1.4.3 * Fix C/C++ problems causing R CMD CHECK errors. * `melt.data.frame()` throws when encountering objects of type `POSIXlt`, and requests a conversion to the (much saner) `POSIXct` type. # Version 1.4.2 * Minor R CMD check fixes for CRAN. # Version 1.4.1 * `melt.data.frame()` now properly sets the OBJECT bit on `value` variable generated if attributes are copied (for example, when multiple POSIXct columns are concatenated to generate the `value` variable) (#50) * `melt.data.frame()` can melt `data.frame`s containing `list` elements as `id` columns. (#49) * `melt.data.frame()` no longer errors when `measure.vars` is `NULL` or empty. (#46) # Version 1.4 * `dcast()` and `acast()` gain a useful error message if you use `value_var` intead of `value.var` (#16), and if `value.var` doesn't exist (#9). They also work better with `.` in specifications like `. ~ .` or `x + y ~ .` * `melt.array()` creates factor variables with levels in the same order as the original rownames (#19) * `melt.data.frame()` gains an internal Rcpp / C++ implementation, and is now many orders of magnitudes faster. It also preserves identical attributes for measure variables, and now throws a warning if they are dropped. (Thanks to Kevin Ushey) * `melt.data.frame()` gains a `factorsAsStrings` argument that controls whether factors are converted to character when melted as measure variables. This is `TRUE` by default for backward compatibility. * `melt.array()` gains a `as.is` argument which can be used to prevent dimnames being converted with `type.convert()` * `recast()` now returns a data frame instead of a list (#45). # Version 1.2.2 * Fix incompatibility with plyr 1.8 * Fix evaluation bug revealed by knitr. (Fixes #18) * Fixed a bug in `melt` where it didn't automatically get variable names when used with tables. (Thanks to Winston Chang) # Version 1.2.1 * Fix bug in multiple margins revealed by plyr 1.7, but caused by mis-use of data frame subsetting. # Version 1.2 * Fixed bug in melt where factors were converted to integers, instead of to characters * When the measured variable is a factor, `dcast` now converts it to a character rather than throwing an error. `acast` still returns a factor matrix. (Thanks to Brian Diggs.) * `acast` is now much faster, due to fixing a very slow way of naming the output. (Thanks to José Bartolomei Díaz for the bug report) * `value_var` argument to `acast` and `dcast` renamed to `value.var` to be consistent with other argument names * Order `NA` factor levels before `(all)` when creating margins * Corrected reshape citation. # Version 1.1 * `melt.data.frame` no longer turns characters into factors * All melt methods gain a `na.rm` and `value.name` arguments - these previously were only possessed by `melt.data.frame` (Fixes #5) reshape2/inst/0000755000176200001440000000000015104642152012740 5ustar liggesusersreshape2/inst/CITATION0000644000176200001440000000056315104637711014106 0ustar liggesusersbibentry( bibtype = "Article", title = "Reshaping Data with the {reshape} Package", author = person("Hadley", "Wickham", role = "aut"), journal = "Journal of Statistical Software", year = "2007", volume = "21", number = "12", pages = "1--20", url = "https://www.jstatsoft.org/v21/i12/" ) reshape2/README.md0000644000176200001440000000507415104637665013265 0ustar liggesusers# reshape2 [![R-CMD-check](https://github.com/hadley/reshape/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/hadley/reshape/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/hadley/reshape/graph/badge.svg)](https://app.codecov.io/gh/hadley/reshape) ## Status [![Lifecycle: superseded](https://img.shields.io/badge/lifecycle-superseded-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#superseded) reshape2 is superseded: only changes necessary to keep it on CRAN will be made. We recommend using [tidyr](https://tidyr.tidyverse.org/) instead. ## Introduction Reshape2 is a reboot of the reshape package. It's been over five years since the first release of reshape, and in that time I've learned a tremendous amount about R programming, and how to work with data in R. Reshape2 uses that knowledge to make a new package for reshaping data that is much more focused and much much faster. This version improves speed at the cost of functionality, so I have renamed it to `reshape2` to avoid causing problems for existing users. Based on user feedback I may reintroduce some of these features. What's new in `reshape2`: * considerably faster and more memory efficient thanks to a much better underlying algorithm that uses the power and speed of subsetting to the fullest extent, in most cases only making a single copy of the data. * cast is replaced by two functions depending on the output type: `dcast` produces data frames, and `acast` produces matrices/arrays. * multidimensional margins are now possible: `grand_row` and `grand_col` have been dropped: now the name of the margin refers to the variable that has its value set to (all). * some features have been removed such as the `|` cast operator, and the ability to return multiple values from an aggregation function. I'm reasonably sure both these operations are better performed by plyr. * a new cast syntax which allows you to reshape based on functions of variables (based on the same underlying syntax as plyr): * better development practices like namespaces and tests. * the function `melt` now names the columns of its returned data frame `Var1`, `Var2`, ..., `VarN` instead of `X1`, `X2`, ..., `XN`. * the argument `variable.name` of `melt` replaces the old argument `variable_name`. Initial benchmarking has shown `melt` to be up to 10x faster, pure reshaping `cast` up to 100x faster, and aggregating `cast()` up to 10x faster. This work has been generously supported by BD (Becton Dickinson). reshape2/man/0000755000176200001440000000000015104637043012541 5ustar liggesusersreshape2/man/melt.default.Rd0000644000176200001440000000150015104637043015410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt.default} \alias{melt.default} \title{Melt a vector. For vectors, makes a column of a data frame} \usage{ \method{melt}{default}(data, ..., na.rm = FALSE, value.name = "value") } \arguments{ \item{data}{vector to melt} \item{...}{further arguments passed to or from other methods.} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{value.name}{name of variable used to store values} } \description{ Melt a vector. For vectors, makes a column of a data frame } \seealso{ \code{\link{melt}}, \code{\link{cast}} Other melt methods: \code{\link{melt.array}()}, \code{\link{melt.data.frame}()}, \code{\link{melt.list}()} } \concept{melt methods} \keyword{manip} reshape2/man/cast.Rd0000644000176200001440000001065715104637043013773 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cast.r \name{cast} \alias{cast} \alias{dcast} \alias{acast} \title{Cast functions Cast a molten data frame into an array or data frame.} \usage{ dcast( data, formula, fun.aggregate = NULL, ..., margins = NULL, subset = NULL, fill = NULL, drop = TRUE, value.var = guess_value(data) ) acast( data, formula, fun.aggregate = NULL, ..., margins = NULL, subset = NULL, fill = NULL, drop = TRUE, value.var = guess_value(data) ) } \arguments{ \item{data}{molten data frame, see \code{\link{melt}}.} \item{formula}{casting formula, see details for specifics.} \item{fun.aggregate}{aggregation function needed if variables do not identify a single observation for each output cell. Defaults to length (with a message) if needed but not specified.} \item{...}{further arguments are passed to aggregating function} \item{margins}{vector of variable names to compute margins for, or TRUE to compute all margins. Any variables that can not be margined over will be silently dropped.} \item{subset}{quoted expression used to subset data prior to reshaping, e.g. \code{subset = .(variable=="length")}.} \item{fill}{value with which to fill in structural missings, defaults to value from applying \code{fun.aggregate} to 0 length vector} \item{drop}{should missing combinations dropped or kept?} \item{value.var}{name of column which stores values, see \code{\link{guess_value}} for default strategies to figure this out.} } \description{ Use \code{acast} or \code{dcast} depending on whether you want vector/matrix/array output or data frame output. Data frames can have at most two dimensions. } \details{ The cast formula has the following format: \code{x_variable + x_2 ~ y_variable + y_2 ~ z_variable ~ ... } The order of the variables makes a difference. The first varies slowest, and the last fastest. There are a couple of special variables: "..." represents all other variables not used in the formula and "." represents no variable, so you can do \code{formula = var1 ~ .}. Alternatively, you can supply a list of quoted expressions, in the form \code{list(.(x_variable, x_2), .(y_variable, y_2), .(z))}. The advantage of this form is that you can cast based on transformations of the variables: \code{list(.(a + b), (c = round(c)))}. See the documentation for \code{\link[plyr]{.}} for more details and alternative formats. If the combination of variables you supply does not uniquely identify one row in the original data set, you will need to supply an aggregating function, \code{fun.aggregate}. This function should take a vector of numbers and return a single summary statistic. } \examples{ #Air quality example names(airquality) <- tolower(names(airquality)) aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE) acast(aqm, day ~ month ~ variable) acast(aqm, month ~ variable, mean) acast(aqm, month ~ variable, mean, margins = TRUE) dcast(aqm, month ~ variable, mean, margins = c("month", "variable")) library(plyr) # needed to access . function acast(aqm, variable ~ month, mean, subset = .(variable == "ozone")) acast(aqm, variable ~ month, mean, subset = .(month == 5)) #Chick weight example names(ChickWeight) <- tolower(names(ChickWeight)) chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE) dcast(chick_m, time ~ variable, mean) # average effect of time dcast(chick_m, diet ~ variable, mean) # average effect of diet acast(chick_m, diet ~ time, mean) # average effect of diet & time # How many chicks at each time? - checking for balance acast(chick_m, time ~ diet, length) acast(chick_m, chick ~ time, mean) acast(chick_m, chick ~ time, mean, subset = .(time < 10 & chick < 20)) acast(chick_m, time ~ diet, length) dcast(chick_m, diet + chick ~ time) acast(chick_m, diet + chick ~ time) acast(chick_m, chick ~ time ~ diet) acast(chick_m, diet + chick ~ time, length, margins="diet") acast(chick_m, diet + chick ~ time, length, drop = FALSE) #Tips example dcast(melt(tips), sex ~ smoker, mean, subset = .(variable == "total_bill")) ff_d <- melt(french_fries, id=1:4, na.rm=TRUE) acast(ff_d, subject ~ time, length) acast(ff_d, subject ~ time, length, fill=0) dcast(ff_d, treatment ~ variable, mean, margins = TRUE) dcast(ff_d, treatment + subject ~ variable, mean, margins="treatment") if (require("lattice")) { lattice::xyplot(`1` ~ `2` | variable, dcast(ff_d, ... ~ rep), aspect="iso") } } \seealso{ \code{\link{melt}}, \url{http://had.co.nz/reshape/} } \keyword{manip} reshape2/man/melt_check.Rd0000644000176200001440000000171115104637043015126 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt_check} \alias{melt_check} \title{Check that input variables to melt are appropriate.} \usage{ melt_check(data, id.vars, measure.vars, variable.name, value.name) } \arguments{ \item{data}{data frame} \item{id.vars}{vector of identifying variable names or indexes} \item{measure.vars}{vector of Measured variable names or indexes} \item{variable.name}{name of variable used to store measured variable names} \item{value.name}{name of variable used to store values} } \value{ a list giving id and measure variables names. } \description{ If id.vars or measure.vars are missing, \code{melt_check} will do its best to impute them. If you only supply one of id.vars and measure.vars, melt will assume the remainder of the variables in the data set belong to the other. If you supply neither, melt will assume discrete variables are id variables and all other are measured. } reshape2/man/melt.array.Rd0000644000176200001440000000310115104637043015101 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt.array} \alias{melt.array} \alias{melt.table} \alias{melt.matrix} \title{Melt an array.} \usage{ \method{melt}{array}( data, varnames = names(dimnames(data)), ..., na.rm = FALSE, as.is = FALSE, value.name = "value" ) \method{melt}{table}( data, varnames = names(dimnames(data)), ..., na.rm = FALSE, as.is = FALSE, value.name = "value" ) \method{melt}{matrix}( data, varnames = names(dimnames(data)), ..., na.rm = FALSE, as.is = FALSE, value.name = "value" ) } \arguments{ \item{data}{array to melt} \item{varnames}{variable names to use in molten data.frame} \item{...}{further arguments passed to or from other methods.} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{as.is}{if \code{FALSE}, the default, dimnames will be converted using \code{\link{type.convert}}. If \code{TRUE}, they will be left as strings.} \item{value.name}{name of variable used to store values} } \description{ This code is conceptually similar to \code{\link{as.data.frame.table}} } \examples{ a <- array(c(1:23, NA), c(2,3,4)) melt(a) melt(a, na.rm = TRUE) melt(a, varnames=c("X","Y","Z")) dimnames(a) <- lapply(dim(a), function(x) LETTERS[1:x]) melt(a) melt(a, varnames=c("X","Y","Z")) dimnames(a)[1] <- list(NULL) melt(a) } \seealso{ \code{\link{cast}} Other melt methods: \code{\link{melt.data.frame}()}, \code{\link{melt.default}()}, \code{\link{melt.list}()} } \concept{melt methods} \keyword{manip} reshape2/man/guess_value.Rd0000644000176200001440000000067115104637043015356 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/helper-guess-value.r \name{guess_value} \alias{guess_value} \title{Guess name of value column} \usage{ guess_value(df) } \arguments{ \item{df}{data frame to guess value column from} } \description{ Strategy: \enumerate{ \item Is value or (all) column present? If so, use that \item Otherwise, guess that last column is the value column } } \keyword{internal} reshape2/man/smiths.Rd0000644000176200001440000000055315104637043014342 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{smiths} \alias{smiths} \title{Demo data describing the Smiths.} \format{ A data frame with 2 rows and 5 variables } \usage{ smiths } \description{ A small demo dataset describing John and Mary Smith. Used in the introductory vignette. } \keyword{datasets} reshape2/man/colsplit.Rd0000644000176200001440000000127715104637043014670 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/helper-colsplit.r \name{colsplit} \alias{colsplit} \title{Split a vector into multiple columns} \usage{ colsplit(string, pattern, names) } \arguments{ \item{string}{character vector or factor to split up} \item{pattern}{regular expression to split on} \item{names}{names for output columns} } \description{ Useful for splitting variable names that a combination of multiple variables. Uses \code{\link{type.convert}} to convert each column to correct type, but will not convert character to factor. } \examples{ x <- c("a_1", "a_2", "b_2", "c_3") vars <- colsplit(x, "_", c("trt", "time")) vars str(vars) } \keyword{manip} reshape2/man/melt.list.Rd0000644000176200001440000000166215104637043014750 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt.list} \alias{melt.list} \title{Melt a list by recursively melting each component.} \usage{ \method{melt}{list}(data, ..., level = 1) } \arguments{ \item{data}{list to recursively melt} \item{...}{further arguments passed to or from other methods.} \item{level}{list level - used for creating labels} } \description{ Melt a list by recursively melting each component. } \examples{ a <- as.list(c(1:4, NA)) melt(a) names(a) <- letters[1:4] melt(a) a <- list(matrix(1:4, ncol=2), matrix(1:6, ncol=2)) melt(a) a <- list(matrix(1:4, ncol=2), array(1:27, c(3,3,3))) melt(a) melt(list(1:5, matrix(1:4, ncol=2))) melt(list(list(1:3), 1, list(as.list(3:4), as.list(1:2)))) } \seealso{ \code{\link{cast}} Other melt methods: \code{\link{melt.array}()}, \code{\link{melt.data.frame}()}, \code{\link{melt.default}()} } \concept{melt methods} \keyword{manip} reshape2/man/parse_formula.Rd0000644000176200001440000000164715104637043015677 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formula.r \name{parse_formula} \alias{parse_formula} \title{Parse casting formulae.} \usage{ parse_formula(formula = "... ~ variable", varnames, value.var = "value") } \arguments{ \item{formula}{formula to parse} \item{varnames}{names of all variables in data} \item{value.var}{name of variable containing values} } \description{ There are a two ways to specify a casting formula: either as a string, or a list of quoted variables. This function converts the former to the latter. } \details{ Casting formulas separate dimensions with \code{~} and variables within a dimension with \code{+} or \code{*}. \code{.} can be used as a placeholder, and \code{...} represents all other variables not otherwise used. } \examples{ reshape2:::parse_formula("a + ...", letters[1:6]) reshape2:::parse_formula("a ~ b + d") reshape2:::parse_formula("a + b ~ c ~ .") } reshape2/man/tips.Rd0000644000176200001440000000162215104637043014010 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{tips} \alias{tips} \title{Tipping data} \format{ A data frame with 244 rows and 7 variables } \usage{ tips } \description{ One waiter recorded information about each tip he received over a period of a few months working in one restaurant. He collected several variables: } \details{ \itemize{ \item tip in dollars, \item bill in dollars, \item sex of the bill payer, \item whether there were smokers in the party, \item day of the week, \item time of day, \item size of the party. } In all he recorded 244 tips. The data was reported in a collection of case studies for business statistics (Bryant & Smith 1995). } \references{ Bryant, P. G. and Smith, M (1995) \emph{Practical Data Analysis: Case Studies in Business Statistics}. Homewood, IL: Richard D. Irwin Publishing: } \keyword{datasets} reshape2/man/french_fries.Rd0000644000176200001440000000142215104637043015464 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{french_fries} \alias{french_fries} \title{Sensory data from a french fries experiment.} \format{ A data frame with 696 rows and 9 variables } \usage{ french_fries } \description{ This data was collected from a sensory experiment conducted at Iowa State University in 2004. The investigators were interested in the effect of using three different fryer oils had on the taste of the fries. } \details{ Variables: \itemize{ \item time in weeks from start of study. \item treatment (type of oil), \item subject, \item replicate, \item potato-y flavour, \item buttery flavour, \item grassy flavour, \item rancid flavour, \item painty flavour } } \keyword{datasets} reshape2/man/melt.Rd0000644000176200001440000000154415104637043013775 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt} \alias{melt} \title{Convert an object into a molten data frame.} \usage{ melt(data, ..., na.rm = FALSE, value.name = "value") } \arguments{ \item{data}{Data set to melt} \item{...}{further arguments passed to or from other methods.} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{value.name}{name of variable used to store values} } \description{ This the generic melt function. See the following functions for the details about different data structures: } \details{ \itemize{ \item \code{\link{melt.data.frame}} for data.frames \item \code{\link{melt.array}} for arrays, matrices and tables \item \code{\link{melt.list}} for lists } } \seealso{ \code{\link{cast}} } \keyword{manip} reshape2/man/margins.Rd0000644000176200001440000000145515104637043014475 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/helper-margins.r \name{margins} \alias{margins} \title{Figure out margining variables.} \usage{ margins(vars, margins = NULL) } \arguments{ \item{vars}{a list of character vectors giving the variables in each dimension} \item{margins}{a character vector of variable names to compute margins for. \code{TRUE} will compute all possible margins.} } \value{ list of margining combinations, or \code{NULL} if none. These are the combinations of variables that should have their values set to \code{(all)} } \description{ Given the variables that form the rows and columns, and a set of desired margins, works out which ones are possible. Variables that can't be margined over are dropped silently. } \keyword{internal} \keyword{manip} reshape2/man/melt.data.frame.Rd0000644000176200001440000000367415104637043016004 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/melt.r \name{melt.data.frame} \alias{melt.data.frame} \title{Melt a data frame into form suitable for easy casting.} \usage{ \method{melt}{data.frame}( data, id.vars, measure.vars, variable.name = "variable", ..., na.rm = FALSE, value.name = "value", factorsAsStrings = TRUE ) } \arguments{ \item{data}{data frame to melt} \item{id.vars}{vector of id variables. Can be integer (variable position) or string (variable name). If blank, will use all non-measured variables.} \item{measure.vars}{vector of measured variables. Can be integer (variable position) or string (variable name)If blank, will use all non id.vars} \item{variable.name}{name of variable used to store measured variable names} \item{...}{further arguments passed to or from other methods.} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{value.name}{name of variable used to store values} \item{factorsAsStrings}{Control whether factors are converted to character when melted as measure variables. When \code{FALSE}, coercion is forced if levels are not identical across the \code{measure.vars}.} } \description{ You need to tell melt which of your variables are id variables, and which are measured variables. If you only supply one of \code{id.vars} and \code{measure.vars}, melt will assume the remainder of the variables in the data set belong to the other. If you supply neither, melt will assume factor and character variables are id variables, and all others are measured. } \examples{ names(airquality) <- tolower(names(airquality)) melt(airquality, id=c("month", "day")) names(ChickWeight) <- tolower(names(ChickWeight)) melt(ChickWeight, id=2:4) } \seealso{ \code{\link{cast}} Other melt methods: \code{\link{melt.array}()}, \code{\link{melt.default}()}, \code{\link{melt.list}()} } \concept{melt methods} \keyword{manip} reshape2/man/add_margins.Rd0000644000176200001440000000107115104637043015277 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/helper-margins.r \name{add_margins} \alias{add_margins} \title{Add margins to a data frame.} \usage{ add_margins(df, vars, margins = TRUE) } \arguments{ \item{df}{input data frame} \item{vars}{a list of character vectors giving the variables in each dimension} \item{margins}{a character vector of variable names to compute margins for. \code{TRUE} will compute all possible margins.} } \description{ Rownames are silently stripped. All margining variables will be converted to factors. } reshape2/man/recast.Rd0000644000176200001440000000142615104637043014314 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/recast.r \name{recast} \alias{recast} \title{Recast: melt and cast in a single step} \usage{ recast(data, formula, ..., id.var, measure.var) } \arguments{ \item{data}{data set to melt} \item{formula}{casting formula, see \code{\link{dcast}} for specifics} \item{...}{other arguments passed to \code{\link{dcast}}} \item{id.var}{identifying variables. If blank, will use all non measure.var variables} \item{measure.var}{measured variables. If blank, will use all non id.var variables} } \description{ This conveniently wraps melting and (d)casting a data frame into a single step. } \examples{ recast(french_fries, time ~ variable, id.var = 1:4) } \seealso{ \url{http://had.co.nz/reshape/} } \keyword{manip} reshape2/DESCRIPTION0000644000176200001440000000147115105023433013470 0ustar liggesusersPackage: reshape2 Title: Flexibly Reshape Data: A Reboot of the Reshape Package Version: 1.4.5 Authors@R: person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre")) Description: Flexibly restructure and aggregate data using just two functions: melt and 'dcast' (or 'acast'). License: MIT + file LICENSE URL: https://github.com/hadley/reshape BugReports: https://github.com/hadley/reshape/issues Depends: R (>= 3.1) Imports: plyr (>= 1.8.1), Rcpp, stringr Suggests: covr, lattice, testthat (>= 3.0.0) LinkingTo: Rcpp Config/testthat/edition: 3 Encoding: UTF-8 LazyData: true RoxygenNote: 7.3.3 NeedsCompilation: yes Packaged: 2025-11-11 14:12:59 UTC; hadleywickham Author: Hadley Wickham [aut, cre] Maintainer: Hadley Wickham Repository: CRAN Date/Publication: 2025-11-12 06:20:11 UTC