reshape2/0000755000176200001440000000000013213533275011767 5ustar liggesusersreshape2/po/0000755000176200001440000000000013213316246012402 5ustar liggesusersreshape2/po/R-reshape.pot0000644000176200001440000000150713213316246014757 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.po0000644000176200001440000000324313213316246013554 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/inst/0000755000176200001440000000000013213327572012745 5ustar liggesusersreshape2/inst/CITATION0000644000176200001440000000117513213316246014102 0ustar liggesuserscitHeader("To cite reshape2 in publications use:") citEntry(entry = "Article", title = "Reshaping Data with the {reshape} Package", author = personList(as.person("Hadley Wickham")), journal = "Journal of Statistical Software", year = "2007", volume = "21", number = "12", pages = "1--20", url = "http://www.jstatsoft.org/v21/i12/", textVersion = paste("Hadley Wickham (2007).", "Reshaping Data with the reshape Package.", "Journal of Statistical Software, 21(12), 1-20.", "URL http://www.jstatsoft.org/v21/i12/.") ) reshape2/tests/0000755000176200001440000000000013213316246013126 5ustar liggesusersreshape2/tests/testthat.R0000644000176200001440000000007413213316246015112 0ustar liggesuserslibrary(testthat) library(reshape2) test_check("reshape2") reshape2/tests/testthat/0000755000176200001440000000000013213533275014771 5ustar liggesusersreshape2/tests/testthat/test-cast.r0000644000176200001440000001500213213316246017056 0ustar liggesuserscontext("cast") s2 <- 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_equivalent(s2, acast(s2m, X1 ~ X2)) expect_equivalent(t(s2), acast(s2m, X2 ~ X1)) expect_equivalent(as.vector(s2), as.vector(acast(s2m, X2 + X1 ~ .))) # 3d expect_equivalent(s3, acast(s3m, X1 ~ X2 ~ X3)) expect_equivalent(as.vector(s3), as.vector(acast(s3m, X3 + X2 + X1 ~ .))) expect_equivalent(aperm(s3, c(1,3,2)), acast(s3m, X1 ~ X3 ~ X2)) expect_equivalent(aperm(s3, c(2,1,3)), acast(s3m, X2 ~ X1 ~ X3)) expect_equivalent(aperm(s3, c(2,3,1)), acast(s3m, X2 ~ X3 ~ X1)) expect_equivalent(aperm(s3, c(3,1,2)), acast(s3m, X3 ~ X1 ~ X2)) expect_equivalent(aperm(s3, c(3,2,1)), acast(s3m, X3 ~ X2 ~ X1)) }) test_that("aggregation matches apply", { # 2d -> 1d expect_equivalent(colMeans(s2), as.vector(acast(s2m, X2 ~ ., mean))) expect_equivalent(rowMeans(s2), as.vector(acast(s2m, X1 ~ ., mean))) # 3d -> 1d expect_equivalent(apply(s3, 1, mean), as.vector(acast(s3m, X1 ~ ., mean))) expect_equivalent(apply(s3, 1, mean), as.vector(acast(s3m, . ~ X1, mean))) expect_equivalent(apply(s3, 2, mean), as.vector(acast(s3m, X2 ~ ., mean))) expect_equivalent(apply(s3, 3, mean), as.vector(acast(s3m, X3 ~ ., mean))) # 3d -> 2d expect_equivalent(apply(s3, c(1,2), mean), acast(s3m, X1 ~ X2, mean)) expect_equivalent(apply(s3, c(1,3), mean), acast(s3m, X1 ~ X3, mean)) expect_equivalent(apply(s3, c(2,3), mean), acast(s3m, X2 ~ X3, mean)) }) 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_that(tab, is_equivalent_to(cst)) }) 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_equivalent(col, colMeans(s2)) expect_equivalent(row, rowMeans(s2)) expect_equivalent(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_that(as.vector(as.matrix(marg)), equals(as.vector(acast(chick_m, time ~ ., length)))) joint <- subset(cast, diet != "(all)") expect_that(joint, is_equivalent_to(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_that(as.vector(acast(df, x + y ~ ., drop = FALSE)), is_equivalent_to(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 <- matrix(names(ffm)[1:5][t(combn(5, 2))], ncol = 2) a_ply(combs, 1, function(vars) { expect_that(count_c(vars), is_equivalent_to(count_t(vars)), label = paste(vars, collapse = ", ")) }) }) 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) df.m <- melt(df) df.m$value2 <- df.m$value * 2 expect_that(acast(df.m, id2 + id1 ~ ., value.var="value")[, 1], equals(1:4, check.attributes = FALSE)) expect_that(acast(df.m, id2 + id1 ~ ., value.var="value2")[, 1], equals(2 * 1:4, check.attributes = FALSE)) }) test_that("labels are correct when missing combinations dropped/kept", { df <- data.frame(fac1 = letters[1:4], fac2 = LETTERS[1:4], x = 1:4) mx <- melt(df, id = c("fac1", "fac2"), measure.var = "x") c1 <- dcast(mx[1:2, ], fac1 + fac2 ~ variable, length, drop = F) expect_that(nrow(c1), equals(16)) c2 <- dcast(droplevels(mx[1:2, ]), fac1 + fac2 ~ variable, length, drop = F) expect_that(nrow(c2), equals(4)) c3 <- dcast(mx[1:2, ], fac1 + fac2 ~ variable, length, drop = T) expect_that(nrow(c3), equals(2)) }) 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_that(nrow(c1), equals(4)) expect_that(ncol(c1), equals(3)) expect_is(c1$x, "character") c2 <- dcast(mx, fac1 ~ fac2 + variable) expect_that(nrow(c2), equals(4)) expect_that(ncol(c2), equals(5)) expect_is(c2$A_x, "character") expect_is(c2$B_x, "character") expect_is(c2$C_x, "character") expect_is(c2$D_x, "character") c3 <- acast(mx, fac1 + fac2 ~ variable) expect_that(nrow(c3), equals(4)) expect_that(ncol(c3), equals(1)) expect_true(is.character(c3)) c4 <- acast(mx, fac1 ~ fac2 + variable) expect_that(nrow(c4), equals(4)) expect_that(ncol(c4), equals(4)) 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)) }) res <- eval(expr, envir = new.env()) expect_equal(names(res), c("y", "b", "a")) }) 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_equal(dim(dcast(mtcars, vs ~ am, value.var = "cyl")), c(2, 3)) }) 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/test-margins.r0000644000176200001440000000217413213316246017572 0ustar liggesuserscontext("Margins") vars <- list(c("a", "b", "c"), c("d", "e", "f")) test_that("margins expanded", { expect_that(margins(vars, "c")[[2]], equals(c("c"))) expect_that(margins(vars, "b")[[2]], equals(c("b", "c"))) expect_that(margins(vars, "a")[[2]], equals(c("a", "b", "c"))) expect_that(margins(vars, "f")[[2]], equals(c("f"))) expect_that(margins(vars, "e")[[2]], equals(c("e", "f"))) expect_that(margins(vars, "d")[[2]], equals(c("d", "e", "f"))) }) test_that("margins intersect", { expect_that(margins(vars, c("c", "f"))[-1], equals(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_that(levels(df2$a), equals(c("a", "b", NA, "(all)"))) df3 <- add_margins(df, c("a", "b")) expect_that(levels(df3$a), equals(c("a", "b", NA, "(all)"))) expect_that(levels(df3$b), equals(c("a", "b", NA, "(all)"))) dc <- dcast(df, a ~ ., margins = TRUE, fun = length) expect_that(levels(dc$a), equals(c("a", "b", NA, "(all)"))) expect_that(as.character(dc$a), equals(c("a", "b", NA, "(all)"))) }) reshape2/tests/testthat/test-melt.r0000644000176200001440000001413513213317613017072 0ustar liggesuserscontext("Melt") test_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_equal(melt(df)$value, v) expect_equal(melt(df, na.rm = TRUE)$value, 1:3) }) 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_equal(names(melt(df, value.name = "v"))[2], "v") }) 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) df.m <- melt(df) expect_true( is.factor(df.m$variable) ) }) 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")) }) 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(m <- melt(df, 1, factorsAsStrings = FALSE)) 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') m <- melt(df) expect_identical(df, m) 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)) library(reshape2) object_bit_set <- function(x) { grepl("\\[OBJ", capture.output(.Internal(inspect(x)))[1]) } t.long <- melt(t.wide, measure.vars=c("t1", "t2", "t3"), value.name="time") expect_true(object_bit_set(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/src/0000755000176200001440000000000013213327572012557 5ustar liggesusersreshape2/src/melt.cpp0000644000176200001440000002355013213327573014232 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(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; \ break; \ } SEXP rep_(SEXP x, int n) { int xn = Rf_length(x); int nout = xn * n; switch (TYPEOF(x)) { case INTSXP: DO_REP(INTSXP, int, INTEGER); case REALSXP: DO_REP(REALSXP, double, REAL); case STRSXP: { int counter = 0; Shield output(Rf_allocVector(STRSXP, nout)); for (int i = 0; i < n; ++i) { for (int j = 0; j < xn; ++j) { SET_STRING_ELT(output, counter, STRING_ELT(x, j)); ++counter; } } return output; break; } case LGLSXP: DO_REP(LGLSXP, int, LOGICAL); case CPLXSXP: DO_REP(CPLXSXP, Rcomplex, COMPLEX); case RAWSXP: DO_REP(RAWSXP, Rbyte, RAW); case VECSXP: { int counter = 0; Shield output(Rf_allocVector(VECSXP, nout)); for (int i = 0; i < n; ++i) { for (int j = 0; j < xn; ++j) { SET_VECTOR_ELT(output, counter, VECTOR_ELT(x, j)); ++counter; } } return output; break; } default: { stop("Unhandled RTYPE"); return R_NilValue; } } } // An optimized rep_each #define DO_REP_EACH(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]; \ ++counter; \ } \ } \ return output; \ break; \ } SEXP rep_each_(SEXP x, int n) { int xn = Rf_length(x); int nout = xn * n; switch (TYPEOF(x)) { case INTSXP: DO_REP_EACH(INTSXP, int, INTEGER); case REALSXP: DO_REP_EACH(REALSXP, double, REAL); case STRSXP: { int counter = 0; Shield output(Rf_allocVector(STRSXP, nout)); for (int i = 0; i < xn; ++i) { for (int j = 0; j < n; ++j) { SET_STRING_ELT(output, counter, STRING_ELT(x, i)); ++counter; } } return output; break; } DO_REP_EACH(STRSXP, SEXP, STRING_PTR); case LGLSXP: DO_REP_EACH(LGLSXP, int, LOGICAL); case CPLXSXP: DO_REP_EACH(CPLXSXP, Rcomplex, COMPLEX); case RAWSXP: DO_REP_EACH(RAWSXP, Rbyte, RAW); case VECSXP: DO_REP_EACH(VECSXP, SEXP, STRING_PTR); 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) { case INTSXP: DO_CONCATENATE(int); case REALSXP: DO_CONCATENATE(double); case LGLSXP: DO_CONCATENATE(int); case CPLXSXP: DO_CONCATENATE(Rcomplex); case STRSXP: { for (int j = 0; j < nrow; ++j) { SET_STRING_ELT(output, i * nrow + j, STRING_ELT(tmp, j)); } break; } case RAWSXP: DO_CONCATENATE(Rbyte); } } return output; } // [[Rcpp::export]] List melt_dataframe(const DataFrame& data, const IntegerVector& id_ind, const IntegerVector& measure_ind, String variable_name, String value_name, SEXP measure_attributes, 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); if (!Rf_isNull(measure_attributes)) { SET_ATTRIB(output[n_id + 1], measure_attributes); // we also need to make sure the OBJECT bit is set for other 'object' types // see: http://stackoverflow.com/questions/24059460/melt-data-frame-changes-behavior-how-posixct-columns-are-printed // if we've entered this code block, the measure_attributes has been // populated because all value variables have identical attributes SET_OBJECT(output[n_id + 1], OBJECT(data[measure_ind[0]])); } // 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.cpp0000644000176200001440000000352613213327573015563 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // melt_dataframe List melt_dataframe(const DataFrame& data, const IntegerVector& id_ind, const IntegerVector& measure_ind, String variable_name, String value_name, SEXP measure_attributes, bool factorsAsStrings, bool valueAsFactor); RcppExport SEXP _reshape2_melt_dataframe(SEXP dataSEXP, SEXP id_indSEXP, SEXP measure_indSEXP, SEXP variable_nameSEXP, SEXP value_nameSEXP, SEXP measure_attributesSEXP, 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< SEXP >::type measure_attributes(measure_attributesSEXP); 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, measure_attributes, factorsAsStrings, valueAsFactor)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_reshape2_melt_dataframe", (DL_FUNC) &_reshape2_melt_dataframe, 8}, {NULL, NULL, 0} }; RcppExport void R_init_reshape2(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } reshape2/NAMESPACE0000644000176200001440000000062413213326636013211 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(plyr) import(stringr) importFrom(Rcpp,evalCpp) importFrom(stats,setNames) importFrom(utils,type.convert) useDynLib(reshape2) reshape2/NEWS.md0000644000176200001440000000547513213317742013077 0ustar liggesusers# 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/data/0000755000176200001440000000000011440164053012672 5ustar liggesusersreshape2/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/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/R/0000755000176200001440000000000013213316246012165 5ustar liggesusersreshape2/R/melt.r0000644000176200001440000002245713213316246013323 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 df <- melt_dataframe( data, as.integer(id.ind-1), as.integer(measure.ind-1), as.character(variable.name), as.character(value.name), as.pairlist(measure.attributes), as.logical(factorsAsStrings), as.logical(valueAsFactor) ) 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 <- sapply(data, is.discrete) 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.r0000644000176200001440000000140613213316246015457 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.r0000644000176200001440000000301513213316246014014 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 (is.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/recast.r0000644000176200001440000000154713213316246013640 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/R/reshape.r0000644000176200001440000000017413213316246014001 0ustar liggesusers##' @importFrom Rcpp evalCpp ##' @importFrom stats setNames ##' @importFrom utils type.convert ##' @useDynLib reshape2 NULL reshape2/R/helper-margins.r0000644000176200001440000000511313213316246015265 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 <- llply(margin_vars, function(vars) { df[vars] <- rep(list(factor("(all)")), length(vars)) df }) rbind.fill(margin_dfs) } reshape2/R/utils.r0000644000176200001440000000260613213316246013514 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/RcppExports.R0000644000176200001440000000066113213316305014600 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, measure_attributes, factorsAsStrings, valueAsFactor) { .Call('_reshape2_melt_dataframe', PACKAGE = 'reshape2', data, id_ind, measure_ind, variable_name, value_name, measure_attributes, factorsAsStrings, valueAsFactor) } reshape2/R/helper-guess-value.r0000644000176200001440000000077113213316246016072 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/cast.r0000644000176200001440000001721413213316246013307 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 (can include "grand\_col" and #' "grand\_row") 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/} #' @import plyr #' @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/data.r0000644000176200001440000000330613213316246013263 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/README.md0000644000176200001440000000516413213327460013251 0ustar liggesusers# reshape2 [![Build Status](https://travis-ci.org/hadley/reshape.svg)](https://travis-ci.org/hadley/reshape) [![Coverage status](https://codecov.io/gh/hadley/reshape/branch/master/graph/badge.svg)](https://codecov.io/github/hadley/reshape?branch=master) ## Status [![lifecycle](https://img.shields.io/badge/lifecycle-retired-orange.svg)](https://img.shields.io/badge/lifecycle-retired-orange.svg) reshape2 is retired: only changes necessary to keep it on CRAN will be made. We recommend using [tidyr](http://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). ## Installation * Get the released version from cran: `install.packages("reshape2")` * Get the dev version from github: `devtools::install_github("hadley/reshape")` reshape2/MD50000644000176200001440000000422013213533275012275 0ustar liggesusersbd2b3ce5627c2303da49703d543f41c6 *DESCRIPTION 581827da3959cce1750fb90f1eb98ec8 *LICENSE fd8905f0d53ec03f481bb242dd7a0e75 *NAMESPACE 9bcfaf5b515bbce1a50525ccf75abcc2 *NEWS.md 98e8d580ad426c9134ed10bb630665f5 *R/RcppExports.R 4aa84b2006ec919fb46cd7b352952916 *R/cast.r 125db94629ec768bc540371316d2eb80 *R/data.r 64787f81028fc99b399324ea1e20d388 *R/formula.r be60b82da1500a97b295ec2eedcbcecd *R/helper-colsplit.r b88bd2b7d2e7ee40cefcf33e6b5145ab *R/helper-guess-value.r 6d720bda805d2903c1cde371a58611ba *R/helper-margins.r 7636e967448a7846e6697cb899c63fb4 *R/melt.r 3b203639e96d72299d6dc7ea6e97a179 *R/recast.r 703f0e7f087a046299646b6519cd9ded *R/reshape.r 2eb44aae9ad8d328afda7379086ec877 *R/utils.r a40f7d6c6db8cf5558b2c23ebe2ae82f *README.md 11d6f343f97ca34edc7cb5ad4a174d05 *data/french_fries.rda 931bb9da3bce71ebcb25ba53c5dcd1e5 *data/smiths.rda 6a3f0a74f813cd68547e665f42b8a3cb *data/tips.rda 12120b1cc03a4e744f04421ef99ebc48 *inst/CITATION c04279b1fa261a1836d61377997b897a *man/add_margins.Rd e45e233fd0f13d69cca64cbc75fae8d6 *man/cast.Rd d7858f9ddfb88fad7f49d4bdca7f7399 *man/colsplit.Rd 91160c0173c8ccfbbd056594e3b4098d *man/french_fries.Rd 3429b8bec5ae06d4244342cf2bbea272 *man/guess_value.Rd 3d35e9af2dbc20ae0a3eaa7ca0572ccd *man/margins.Rd d6f2f4a84a074f2dfdcd4e657dc82f62 *man/melt.Rd 6b35e1f77442719cc167abad16536480 *man/melt.array.Rd 84831fccbfe80527fcf68b9374fc439d *man/melt.data.frame.Rd dd5f5a5590938da1585a4346cb6ff119 *man/melt.default.Rd 69aa9382d55ace3e3c450954c1d99119 *man/melt.list.Rd 06a1a5d8c52c5c58d5e76039100af4a2 *man/melt_check.Rd cd76f45422652e41d176fa7eccd55442 *man/parse_formula.Rd 790574147a29c7f0679fba4fec3d4c3b *man/recast.Rd 0f2864b3309a3919564412f370a60f9f *man/smiths.Rd a86c12a7bc2b7cf19de2baf23283f109 *man/tips.Rd 2dbab2cfefc21e9c3d9b44d60b2cc771 *po/R-ko.po 15d543bb8dc1c303c8f4a9f54ef767ef *po/R-reshape.pot c3dccb2918ad5920239995f2a462edf4 *src/RcppExports.cpp 02411276cbb3c1febc3fa19909e86975 *src/melt.cpp cbd1f6d4b546516421d74e001e092bbb *tests/testthat.R 396d0d07c44ceeb304947ec03c2286d1 *tests/testthat/test-cast.r c450402fc64e0d1a35d777917ff93ad0 *tests/testthat/test-margins.r 5579d0adc40b5a37ca47aa09e27cd7d9 *tests/testthat/test-melt.r reshape2/DESCRIPTION0000644000176200001440000000132213213533275013473 0ustar liggesusersPackage: reshape2 Title: Flexibly Reshape Data: A Reboot of the Reshape Package Version: 1.4.3 Author: Hadley Wickham Maintainer: Hadley Wickham 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 (>= 0.8.0) LinkingTo: Rcpp Encoding: UTF-8 LazyData: true RoxygenNote: 6.0.1.9000 NeedsCompilation: yes Packaged: 2017-12-10 22:04:42 UTC; hadley Repository: CRAN Date/Publication: 2017-12-11 16:47:57 UTC reshape2/man/0000755000176200001440000000000013213316246012537 5ustar liggesusersreshape2/man/melt.list.Rd0000644000176200001440000000165513213316317014747 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/melt.data.frame.Rd0000644000176200001440000000365113213316317015774 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/cast.Rd0000644000176200001440000001067113213316317013764 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 (can include "grand\_col" and "grand\_row") 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.array.Rd0000644000176200001440000000303013213316317015077 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/smiths.Rd0000644000176200001440000000055113213316317014335 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.Rd0000644000176200001440000000127713213316317014665 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/parse_formula.Rd0000644000176200001440000000164713213316317015674 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/melt_check.Rd0000644000176200001440000000171113213316317015123 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.default.Rd0000644000176200001440000000147313213316317015416 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/tips.Rd0000644000176200001440000000162013213316317014003 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/add_margins.Rd0000644000176200001440000000107113213316317015274 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/melt.Rd0000644000176200001440000000154413213316317013772 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/guess_value.Rd0000644000176200001440000000067113213316317015353 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/margins.Rd0000644000176200001440000000145513213316317014472 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/recast.Rd0000644000176200001440000000142613213316317014311 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/man/french_fries.Rd0000644000176200001440000000142013213316317015457 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/LICENSE0000644000176200001440000000006113002467640012767 0ustar liggesusersYEAR: 2008-2016 COPYRIGHT HOLDER: Hadley Wickham