reshape2/0000755000175100001440000000000013002636301011773 5ustar hornikusersreshape2/po/0000755000175100001440000000000013002467630012420 5ustar hornikusersreshape2/po/R-reshape.pot0000644000175100001440000000150713002467630014775 0ustar hornikusersmsgid "" 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.po0000644000175100001440000000324313002467630013572 0ustar hornikusers# 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/0000755000175100001440000000000013002467747012770 5ustar hornikusersreshape2/inst/CITATION0000644000175100001440000000117513002467630014120 0ustar hornikuserscitHeader("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/0000755000175100001440000000000013002467630013144 5ustar hornikusersreshape2/tests/testthat.R0000644000175100001440000000007413002467630015130 0ustar hornikuserslibrary(testthat) library(reshape2) test_check("reshape2") reshape2/tests/testthat/0000755000175100001440000000000013002636301014775 5ustar hornikusersreshape2/tests/testthat/test-cast.r0000644000175100001440000001500213002467630017074 0ustar hornikuserscontext("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.r0000644000175100001440000000217413002467630017610 0ustar hornikuserscontext("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.r0000644000175100001440000001361613002467630017114 0ustar hornikuserscontext("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) }) reshape2/src/0000755000175100001440000000000013002467747012602 5ustar hornikusersreshape2/src/melt.cpp0000644000175100001440000002253613002467747014257 0ustar hornikusers#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: DO_REP(VECSXP, SEXP, STRING_PTR); 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(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); REP(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.cpp0000644000175100001440000000306013002467747015576 0ustar hornikusers// 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 } reshape2/NAMESPACE0000644000175100001440000000062413002467630013223 0ustar hornikusers# 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/data/0000755000175100001440000000000011440164053012710 5ustar hornikusersreshape2/data/smiths.rda0000644000175100001440000000037312057435674014731 0ustar hornikusers r0b```b`b@& `d`lŹ% @P 3/X5XFUZT USM,X 3--1$a>?HEp0_|ccu.ۂ%KM9 Ҥ($37fNL1S33`2<9`VrA2G ĒDDP>breshape2/data/tips.rda0000644000175100001440000000504412057435674014401 0ustar hornikusersݚ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/0000755000175100001440000000000013002467630012203 5ustar hornikusersreshape2/R/melt.r0000644000175100001440000002245713002467630013341 0ustar hornikusers#' 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.r0000644000175100001440000000140613002467630015475 0ustar hornikusers#' 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.r0000644000175100001440000000301513002467630014032 0ustar hornikusers#' 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.r0000644000175100001440000000154713002467630013656 0ustar hornikusers#' 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.r0000644000175100001440000000017413002467630014017 0ustar hornikusers##' @importFrom Rcpp evalCpp ##' @importFrom stats setNames ##' @importFrom utils type.convert ##' @useDynLib reshape2 NULL reshape2/R/helper-margins.r0000644000175100001440000000511313002467630015303 0ustar hornikusers#' 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.r0000644000175100001440000000260613002467630013532 0ustar hornikusers"%||%" <- 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.R0000644000175100001440000000066013002467630014621 0ustar hornikusers# 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.r0000644000175100001440000000077113002467630016110 0ustar hornikusers#' 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.r0000644000175100001440000001721413002467630013325 0ustar hornikusers#' 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.r0000644000175100001440000000330613002467630013301 0ustar hornikusers#' 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.md0000644000175100001440000000426313002467630013266 0ustar hornikusers# 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 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/MD50000644000175100001440000000414613002636301012310 0ustar hornikusersa0e1a31261ff65c15a21c969b20f17d1 *DESCRIPTION 581827da3959cce1750fb90f1eb98ec8 *LICENSE fd8905f0d53ec03f481bb242dd7a0e75 *NAMESPACE 6a66deb772bc6ecf31259089b452bc7c *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 7af06153ad01e703989e7cb74d4bac0e *README.md 11d6f343f97ca34edc7cb5ad4a174d05 *data/french_fries.rda 931bb9da3bce71ebcb25ba53c5dcd1e5 *data/smiths.rda 6a3f0a74f813cd68547e665f42b8a3cb *data/tips.rda 12120b1cc03a4e744f04421ef99ebc48 *inst/CITATION a38ffdf6acadf4af0515ae5b642afc2c *man/add_margins.Rd 0ce186534dd3131776b4915d4773451f *man/cast.Rd 3471d7f0ce1a7d0e2745b625d7465644 *man/colsplit.Rd 741274273dd9f76bb7603c94b82ac138 *man/french_fries.Rd 508cde91850c9962138209d2d2736c9f *man/guess_value.Rd 5eb1133a68f4fa75fac9963e0402148e *man/margins.Rd c03f16a2ea0f929fdd8375ca23895f99 *man/melt.Rd 9d052c6c754bb0c3a09116d8ca2a0b93 *man/melt.array.Rd 62d1f360a21de36c15b44c99e6ed5579 *man/melt.data.frame.Rd 6276fd04f602353d70bf0b90d28796de *man/melt.default.Rd b6eae2d0f433f7b270dd580eeb21aa61 *man/melt.list.Rd 6c5033a09e652c0f66d0b3bfcc44f28b *man/melt_check.Rd 2a0c5e81d167736049f0ff2c586a553a *man/parse_formula.Rd 56793152e808c20eaeb1425f3ec44663 *man/recast.Rd bea4b7e556999fd38bd34d73ec6eee76 *man/smiths.Rd dfe78bdd1430ab01bf4df7fbb4bc0086 *man/tips.Rd 2dbab2cfefc21e9c3d9b44d60b2cc771 *po/R-ko.po 15d543bb8dc1c303c8f4a9f54ef767ef *po/R-reshape.pot c72ed0dd7a3c63042e0ce76c6017ed8f *src/RcppExports.cpp bffca058114bf27e81d160715d2e3b6a *src/melt.cpp cbd1f6d4b546516421d74e001e092bbb *tests/testthat.R 396d0d07c44ceeb304947ec03c2286d1 *tests/testthat/test-cast.r c450402fc64e0d1a35d777917ff93ad0 *tests/testthat/test-margins.r b8d8c0d166945ea0c6ac52a6444146f6 *tests/testthat/test-melt.r reshape2/DESCRIPTION0000644000175100001440000000124413002636301013502 0ustar hornikusersPackage: reshape2 Title: Flexibly Reshape Data: A Reboot of the Reshape Package Version: 1.4.2 Author: Hadley Wickham Maintainer: Hadley Wickham Description: Flexibly restructure and aggregate data using just two functions: melt and 'dcast' (or 'acast'). URL: https://github.com/hadley/reshape BugReports: https://github.com/hadley/reshape/issues LinkingTo: Rcpp Imports: plyr (>= 1.8.1), stringr, Rcpp Suggests: testthat (>= 0.8.0), lattice License: MIT + file LICENSE LazyData: true RoxygenNote: 5.0.1.9000 NeedsCompilation: yes Packaged: 2016-10-21 19:43:35 UTC; hadley Repository: CRAN Date/Publication: 2016-10-22 12:17:37 reshape2/man/0000755000175100001440000000000013002467630012555 5ustar hornikusersreshape2/man/melt.list.Rd0000644000175100001440000000162713002467630014765 0ustar hornikusers% 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}} } \keyword{manip} reshape2/man/melt.data.frame.Rd0000644000175100001440000000362313002467630016012 0ustar hornikusers% 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}} } \keyword{manip} reshape2/man/cast.Rd0000644000175100001440000001067213002467630014004 0ustar hornikusers% 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.Rd0000644000175100001440000000300213002467630015115 0ustar hornikusers% 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}} } \keyword{manip} reshape2/man/smiths.Rd0000644000175100001440000000055213002467630014355 0ustar hornikusers% 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.Rd0000644000175100001440000000130013002467630014667 0ustar hornikusers% 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.Rd0000644000175100001440000000165013002467630015705 0ustar hornikusers% 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.Rd0000644000175100001440000000171213002467630015143 0ustar hornikusers% 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.Rd0000644000175100001440000000144513002467630015434 0ustar hornikusers% 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}} } \keyword{manip} reshape2/man/tips.Rd0000644000175100001440000000162113002467630014023 0ustar hornikusers% 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.Rd0000644000175100001440000000107213002467630015314 0ustar hornikusers% 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.Rd0000644000175100001440000000154513002467630014012 0ustar hornikusers% 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.Rd0000644000175100001440000000067213002467630015373 0ustar hornikusers% 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.Rd0000644000175100001440000000145613002467630014512 0ustar hornikusers% 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.Rd0000644000175100001440000000142713002467630014331 0ustar hornikusers% 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.Rd0000644000175100001440000000142113002467630015477 0ustar hornikusers% 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/LICENSE0000644000175100001440000000006113002467640013005 0ustar hornikusersYEAR: 2008-2016 COPYRIGHT HOLDER: Hadley Wickham