reshape2/0000755000176000001440000000000012325747544012030 5ustar ripleyusersreshape2/po/0000755000176000001440000000000012325506434012435 5ustar ripleyusersreshape2/po/R-reshape.pot0000644000176000001440000000150712325506434015012 0ustar ripleyusersmsgid "" 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.po0000644000176000001440000000324312325506434013607 0ustar ripleyusers# 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/0000755000176000001440000000000012325727077013004 5ustar ripleyusersreshape2/inst/CITATION0000644000176000001440000000117412325506434014134 0ustar ripleyuserscitHeader("To cite reshape 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/0000755000176000001440000000000012325506434013161 5ustar ripleyusersreshape2/tests/testthat.R0000644000176000001440000000007412325506434015145 0ustar ripleyuserslibrary(testthat) library(reshape2) test_check("reshape2") reshape2/tests/testthat/0000755000176000001440000000000012325747544015032 5ustar ripleyusersreshape2/tests/testthat/test-cast.r0000644000176000001440000001500212325506434017111 0ustar ripleyuserscontext("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.r0000644000176000001440000000217412325506434017625 0ustar ripleyuserscontext("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.r0000644000176000001440000001124512325506434017125 0ustar ripleyuserscontext("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" ) }) reshape2/src/0000755000176000001440000000000012325727077012616 5ustar ripleyusersreshape2/src/melt.cpp0000644000176000001440000002175612325727077014276 0ustar ripleyusers#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); 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); 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(); int ncol = data.size(); CharacterVector data_names = as(data.attr("names")); // We only melt data.frames that contain only atomic elements for (int i = 0; i < ncol; ++i) { if (!Rf_isVectorAtomic(data[i])) { stop("Can't melt data.frames with non-atomic columns"); } } 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)); // 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(RTYPE) \ case RTYPE: { \ output[i] = rep_(data[id_ind[i]], n_measure); \ Rf_copyMostAttrib(data[id_ind[i]], output[i]); \ break; \ } for (int i = 0; i < n_id; ++i) { switch (TYPEOF(data[id_ind[i]])) { REP(LGLSXP); REP(INTSXP); REP(REALSXP); REP(STRSXP); REP(CPLXSXP); REP(RAWSXP); 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); } // Set the object bit explicitly to make sure that the 'value' is properly // interpreted as a factor if (valueAsFactor) { SET_OBJECT(output[n_id + 1], 1); } // 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.cpp0000644000176000001440000000320212325727077015610 0ustar ripleyusers// This file was generated by Rcpp::compileAttributes // 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 SEXP __sexp_result; { Rcpp::RNGScope __rngScope; 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 ); List __result = melt_dataframe(data, id_ind, measure_ind, variable_name, value_name, measure_attributes, factorsAsStrings, valueAsFactor); PROTECT(__sexp_result = Rcpp::wrap(__result)); } UNPROTECT(1); return __sexp_result; END_RCPP } reshape2/NAMESPACE0000644000176000001440000000054212325506434013237 0ustar ripleyusers# Generated by roxygen2 (4.0.0): 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) useDynLib(reshape2) reshape2/data/0000755000176000001440000000000011440164053012722 5ustar ripleyusersreshape2/data/smiths.rda0000644000176000001440000000037312057435674014743 0ustar ripleyusers r0b```b`b@& `d`lŹ% @P 3/X5XFUZT USM,X 3--1$a>?HEp0_|ccu.ۂ%KM9 Ҥ($37fNL1S33`2<9`VrA2G ĒDDP>breshape2/data/tips.rda0000644000176000001440000000504412057435674014413 0ustar ripleyusersݚ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/0000755000176000001440000000000012325506434012220 5ustar ripleyusersreshape2/R/melt.r0000644000176000001440000002227312325506434013352 0ustar ripleyusers#' 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)) ## 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.r0000644000176000001440000000140612325506434015512 0ustar ripleyusers#' 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.r0000644000176000001440000000301512325506434014047 0ustar ripleyusers#' 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.r0000644000176000001440000000154712325506434013673 0ustar ripleyusers#' 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.r0000644000176000001440000000007112325506434014030 0ustar ripleyusers##' @importFrom Rcpp evalCpp ##' @useDynLib reshape2 NULLreshape2/R/helper-margins.r0000644000176000001440000000511312325506434015320 0ustar ripleyusers#' 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.r0000644000176000001440000000260612325506434013547 0ustar ripleyusers"%||%" <- 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.R0000644000176000001440000000063712325506434014642 0ustar ripleyusers# This file was generated by Rcpp::compileAttributes # 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.r0000644000176000001440000000077112325506434016125 0ustar ripleyusers#' 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.r0000644000176000001440000001721412325506434013342 0ustar ripleyusers#' 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.r0000644000176000001440000000350312325506434013315 0ustar ripleyusers#' 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 #' @name french_fries #' @usage data(french_fries) #' @format A data frame with 696 rows and 9 variables #' @keywords datasets NULL #' Demo data describing the Smiths. #' #' A small demo dataset describing John and Mary Smith. Used in the #' introductory vignette. #' #' @docType data #' @name smiths #' @usage data(smiths) #' @format A data frame with 2 rows and 5 variables #' @keywords datasets NULL #' 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: #' @docType data #' @name tips #' @usage data(tips) #' @format A data frame with 244 rows and 7 variables #' @keywords datasets NULL reshape2/README.md0000644000176000001440000000426512325506434013305 0ustar ripleyusers# Reshape2 [![Build Status](https://travis-ci.org/hadley/reshape.png)](https://travis-ci.org/hadley/reshape) 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 focussed 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/reshape2")` reshape2/MD50000644000176000001440000000414612325747544012345 0ustar ripleyusers80e1197e01ef035042dac55a858ffd16 *DESCRIPTION c7ea166b434ab74f81ce002ea5d87b07 *LICENSE 49177420adf56e29f1e6df797daa4fd7 *NAMESPACE a41923a0c3dd9c64e173686355479ae1 *R/RcppExports.R 4aa84b2006ec919fb46cd7b352952916 *R/cast.r 827ca227c89be29638317fd0cf09810d *R/data.r 64787f81028fc99b399324ea1e20d388 *R/formula.r be60b82da1500a97b295ec2eedcbcecd *R/helper-colsplit.r b88bd2b7d2e7ee40cefcf33e6b5145ab *R/helper-guess-value.r 6d720bda805d2903c1cde371a58611ba *R/helper-margins.r 8ac26acd4388cd90ba9d4601def9c412 *R/melt.r 3b203639e96d72299d6dc7ea6e97a179 *R/recast.r 56fe864c06a775eaaa3c4c39aa013415 *R/reshape.r 2eb44aae9ad8d328afda7379086ec877 *R/utils.r 1269f00722e814c55c8b4052cf5a03c4 *README.md 11d6f343f97ca34edc7cb5ad4a174d05 *data/french_fries.rda 931bb9da3bce71ebcb25ba53c5dcd1e5 *data/smiths.rda 6a3f0a74f813cd68547e665f42b8a3cb *data/tips.rda dd664ad85751a470cf0b7414a1c4c3ec *inst/CITATION 760d53a13108f2f2688d3f48e0587389 *man/add_margins.Rd c3c5e1ece6293a89672a4e67fef1846d *man/cast.Rd 9825c4f987358217df32f752a52de468 *man/colsplit.Rd 1d1e6853db07b4f2669f486dd65a4309 *man/french_fries.Rd 248ac8ff74c1ea6bd6c52ff30eddf82f *man/guess_value.Rd b43ca4b201b16cde1e6737099b122ac7 *man/margins.Rd 62667b517bb67a06e4696238870260e3 *man/melt.Rd 75d51e9dd1a45b61820847572250e081 *man/melt.array.Rd 5a4f897301abfee4dcbf5a5fba1450a4 *man/melt.data.frame.Rd 0a774f8518bb460b63853938ed3d75ce *man/melt.default.Rd 8f56b5e3474bef6f0db9e5be64900d29 *man/melt.list.Rd f409237630dbedee29ed98ff30f7b782 *man/melt_check.Rd 69465c7fa930c098d075dabc149576af *man/parse_formula.Rd c1e35b037d85d451808f9397a774c1d6 *man/recast.Rd 56ebb0580192b71037dbc17b4963283d *man/smiths.Rd 207d6da0290afadcdc17c39c5a30c456 *man/tips.Rd 2dbab2cfefc21e9c3d9b44d60b2cc771 *po/R-ko.po 15d543bb8dc1c303c8f4a9f54ef767ef *po/R-reshape.pot be0ef27f9591d078302bf4f59bb0d03f *src/RcppExports.cpp e47f1fa8028888545cc472508db272df *src/melt.cpp cbd1f6d4b546516421d74e001e092bbb *tests/testthat.R 396d0d07c44ceeb304947ec03c2286d1 *tests/testthat/test-cast.r c450402fc64e0d1a35d777917ff93ad0 *tests/testthat/test-margins.r 3b67b1ae2f6541474bfcf563381d3c78 *tests/testthat/test-melt.r reshape2/DESCRIPTION0000644000176000001440000000126612325747544013543 0ustar ripleyusersPackage: reshape2 Type: Package Title: Flexibly reshape data: a reboot of the reshape package. Version: 1.4 Author: Hadley Wickham Maintainer: Hadley Wickham Description: Reshape lets you flexibly restructure and aggregate data using just two functions: melt and cast. URL: https://github.com/hadley/reshape BugReports: https://github.com/hadley/reshape/issues LinkingTo: Rcpp Imports: plyr (>= 1.8.1), stringr, Rcpp Roxygen: list(wrap = FALSE) Suggests: testthat (>= 0.8.0), lattice License: MIT + file LICENSE LazyData: true Packaged: 2014-04-23 12:12:47 UTC; hadley NeedsCompilation: yes Repository: CRAN Date/Publication: 2014-04-23 16:34:12 reshape2/man/0000755000176000001440000000000012325507767012604 5ustar ripleyusersreshape2/man/melt.list.Rd0000644000176000001440000000165612325507767015016 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.matrix}}, \code{\link{melt.table}}; \code{\link{melt.data.frame}}; \code{\link{melt.default}} } \keyword{manip} reshape2/man/melt.data.frame.Rd0000644000176000001440000000365212325507767016043 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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{value.name}{name of variable used to store values} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{...}{further arguments passed to or from other methods.} \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.matrix}}, \code{\link{melt.table}}; \code{\link{melt.default}}; \code{\link{melt.list}} } \keyword{manip} reshape2/man/cast.Rd0000644000176000001440000001063212325507767014027 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \name{cast} \alias{acast} \alias{cast} \alias{dcast} \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.Rd0000644000176000001440000000274212325507767015156 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \name{melt.array} \alias{melt.array} \alias{melt.matrix} \alias{melt.table} \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{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} \item{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} } \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}} } \keyword{manip} reshape2/man/smiths.Rd0000644000176000001440000000052012325507767014377 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \docType{data} \name{smiths} \alias{smiths} \title{Demo data describing the Smiths.} \format{A data frame with 2 rows and 5 variables} \usage{ data(smiths) } \description{ A small demo dataset describing John and Mary Smith. Used in the introductory vignette. } \keyword{datasets} reshape2/man/colsplit.Rd0000644000176000001440000000122512325507767014724 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000160512325507767015734 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000165212325507767015175 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000147412325507767015465 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{...}{further arguments passed to or from other methods.} \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.matrix}}, \code{\link{melt.table}}; \code{\link{melt.data.frame}}; \code{\link{melt.list}} } \keyword{manip} reshape2/man/tips.Rd0000644000176000001440000000156712325507767014063 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \docType{data} \name{tips} \alias{tips} \title{Tipping data} \format{A data frame with 244 rows and 7 variables} \usage{ data(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.Rd0000644000176000001440000000102012325507767015334 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000150512325507767014035 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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{na.rm}{Should NA values be removed from the data set? This will convert explicit missings to implicit missings.} \item{...}{further arguments passed to or from other methods.} \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.Rd0000644000176000001440000000061412325507767015416 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000140412325507767014532 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000136512325507767014361 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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.Rd0000644000176000001440000000136712325507767015537 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \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{ data(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/LICENSE0000644000176000001440000000006112325727026013023 0ustar ripleyusersYEAR: 2008-2014 COPYRIGHT HOLDER: Hadley Wickham