test_that("can pivot all cols to long", { df <- tibble(x = 1:2, y = 3:4) pv <- pivot_longer(df, x:y) expect_named(pv, c("name", "value")) expect_equal(pv$name, rep(names(df), 2)) expect_equal(pv$value, c(1, 3, 2, 4)) }) test_that("values interleaved correctly", { df <- tibble( x = c(1, 2), y = c(10, 20), z = c(100, 200), ) pv <- pivot_longer(df, 1:3) expect_equal(pv$value, c(1, 10, 100, 2, 20, 200)) }) test_that("can add multiple columns from spec", { df <- tibble(x = 1:2, y = 3:4) sp <- tibble(.name = c("x", "y"), .value = "v", a = 1, b = 2) pv <- pivot_longer_spec(df, spec = sp) expect_named(pv, c("a", "b", "v")) }) test_that("preserves original keys", { df <- tibble(x = 1:2, y = 2, z = 1:2) pv <- pivot_longer(df, y:z) expect_named(pv, c("x", "name", "value")) expect_equal(pv$x, rep(df$x, each = 2)) }) test_that("can drop missing values", { df <- data.frame(x = c(1, NA), y = c(NA, 2)) pv <- pivot_longer(df, x:y, values_drop_na = TRUE) expect_equal(pv$name, c("x", "y")) expect_equal(pv$value, c(1, 2)) }) test_that("can handle missing combinations", { df <- tribble( ~id, ~x_1, ~x_2, ~y_2, "A", 1, 2, "a", "B", 3, 4, "b", ) pv <- pivot_longer(df, -id, names_to = c(".value", "n"), names_sep = "_") expect_named(pv, c("id", "n", "x", "y")) expect_equal(pv$x, 1:4) expect_equal(pv$y, c(NA, "a", NA, "b")) }) test_that("mixed columns are automatically coerced", { df <- data.frame(x = factor("a"), y = factor("b")) pv <- pivot_longer(df, x:y) expect_equal(pv$value, factor(c("a", "b"))) }) test_that("can override default output column type", { df <- tibble(x = "x", y = 1L) pv <- pivot_longer(df, x:y, values_transform = list(value = as.list)) expect_equal(pv$value, list("x", 1)) }) test_that("can pivot to multiple measure cols", { df <- tibble(x = "x", y = 1) sp <- tribble( ~.name, ~.value, ~row, "x", "X", 1, "y", "Y", 1, ) pv <- pivot_longer_spec(df, sp) expect_named(pv, c("row", "X", "Y")) expect_equal(pv$X, "x") expect_equal(pv$Y, 1) }) test_that("original col order is preserved", { df <- tribble( ~id, ~z_1, ~y_1, ~x_1, ~z_2, ~y_2, ~x_2, "A", 1, 2, 3, 4, 5, 6, "B", 7, 8, 9, 10, 11, 12, ) pv <- pivot_longer(df, -id, names_to = c(".value", "n"), names_sep = "_") expect_named(pv, c("id", "n", "z", "y", "x")) }) test_that("handles duplicated column names", { df <- tibble(x = 1, a = 1, a = 2, b = 3, b = 4, .name_repair = "minimal") pv <- pivot_longer(df, -x) expect_named(pv, c("x", "name", "value")) expect_equal(pv$name, c("a", "a", "b", "b")) expect_equal(pv$value, 1:4) }) test_that("can pivot duplicated names to .value", { df <- tibble(x = 1, a_1 = 1, a_2 = 2, b_1 = 3, b_2 = 4) pv1 <- pivot_longer(df, -x, names_to = c(".value", NA), names_sep = "_") pv2 <- pivot_longer(df, -x, names_to = c(".value", NA), names_pattern = "(.)_(.)") pv3 <- pivot_longer(df, -x, names_to = ".value", names_pattern = "(.)_.") expect_named(pv1, c("x", "a", "b")) expect_equal(pv1$a, c(1, 2)) expect_equal(pv2, pv1) expect_equal(pv3, pv1) }) test_that(".value can be at any position in `names_to`", { samp <- tibble( i = 1:4, y_t1 = rnorm(4), y_t2 = rnorm(4), z_t1 = rep(3, 4), z_t2 = rep(-2, 4), ) value_first <- pivot_longer(samp, -i, names_to = c(".value", "time"), names_sep = "_") samp2 <- dplyr::rename(samp, t1_y = y_t1, t2_y = y_t2, t1_z = z_t1, t2_z = z_t2) value_second <- pivot_longer(samp2, -i, names_to = c("time", ".value"), names_sep = "_") expect_identical(value_first, value_second) }) test_that("type error message use variable names", { df <- data.frame(abc = 1, xyz = "b") err <- capture_error(pivot_longer(df, everything())) expect_s3_class(err, "vctrs_error_incompatible_type") expect_equal(err$x_arg, "abc") expect_equal(err$y_arg, "xyz") }) test_that("when `values_ptypes` is provided, the type error uses variable names (#1364)", { df <- tibble(x = 1) expect_snapshot({ (expect_error(pivot_longer(df, x, values_ptypes = character()))) }) }) test_that("when `names_ptypes` is provided, the type error uses `names_to` names (#1364)", { df <- tibble(x = 1) expect_snapshot({ (expect_error({ pivot_longer( df, cols = x, names_to = "name", names_ptypes = double() ) })) }) }) test_that("error when overwriting existing column", { df <- tibble(x = 1, y = 2) expect_snapshot( (expect_error(pivot_longer(df, y, names_to = "x"))) ) expect_snapshot( out <- pivot_longer(df, y, names_to = "x", names_repair = "unique") ) expect_named(out, c("x...1", "x...2", "value")) }) test_that("grouping is preserved", { df <- tibble(g = 1, x1 = 1, x2 = 2) out <- df %>% dplyr::group_by(g) %>% pivot_longer(x1:x2, names_to = "x", values_to = "v") expect_equal(dplyr::group_vars(out), "g") }) test_that("zero row data frame works", { df <- tibble(x = integer(), y = integer()) pv <- pivot_longer(df, x:y) expect_named(pv, c("name", "value")) expect_equal(pv$name, character()) expect_equal(pv$value, integer()) }) test_that("`cols_vary` can adjust the resulting row ordering (#1312)", { df <- tibble(x = c(1, 2), y = c(3, 4)) expect_identical( pivot_longer(df, c(x, y), cols_vary = "fastest"), tibble(name = c("x", "y", "x", "y"), value = c(1, 3, 2, 4)) ) expect_identical( pivot_longer(df, c(x, y), cols_vary = "slowest"), tibble(name = c("x", "x", "y", "y"), value = c(1, 2, 3, 4)) ) }) test_that("`cols_vary` works with id columns not part of the pivoting process", { df <- tibble(id = c("a", "b"), x = c(1, 2), y = c(3, 4)) out <- pivot_longer(df, c(x, y), cols_vary = "fastest") expect_identical(out$id, c("a", "a", "b", "b")) expect_identical( out[c("name", "value")], pivot_longer(df[c("x", "y")], c(x, y), cols_vary = "fastest") ) out <- pivot_longer(df, c(x, y), cols_vary = "slowest") expect_identical(out$id, c("a", "b", "a", "b")) expect_identical( out[c("name", "value")], pivot_longer(df[c("x", "y")], c(x, y), cols_vary = "slowest") ) }) test_that("adjusting `cols_vary` works fine with `values_drop_na`", { df <- tibble(id = c("a", "b"), x = c(1, NA), y = c(3, 4)) expect_identical( pivot_longer(df, c(x, y), cols_vary = "slowest", values_drop_na = TRUE), tibble( id = c("a", "a", "b"), name = c("x", "y", "y"), value = c(1, 3, 4) ) ) }) # spec -------------------------------------------------------------------- test_that("validates inputs", { df <- tibble(x = 1) expect_error(build_longer_spec(df, x, values_to = letters[1:2]), class = "vctrs_error_assert" ) }) test_that("no names doesn't generate names (#1120)", { df <- tibble(x = 1) expect_identical( colnames(build_longer_spec(df, x, names_to = character())), c(".name", ".value") ) expect_identical( colnames(build_longer_spec(df, x, names_to = NULL)), c(".name", ".value") ) }) test_that("multiple names requires names_sep/names_pattern", { df <- tibble(x_y = 1) expect_snapshot({ (expect_error(build_longer_spec(df, x_y, names_to = c("a", "b")))) (expect_error( build_longer_spec( df, x_y, names_to = c("a", "b"), names_sep = "x", names_pattern = "x" ) )) }) }) test_that("names_sep generates correct spec", { df <- tibble(x_y = 1) sp <- build_longer_spec(df, x_y, names_to = c("a", "b"), names_sep = "_") expect_equal(sp$a, "x") expect_equal(sp$b, "y") }) test_that("names_sep fails with single name", { df <- tibble(x_y = 1) expect_snapshot({ (expect_error(build_longer_spec(df, x_y, names_to = "x", names_sep = "_"))) }) }) test_that("names_pattern generates correct spec", { df <- tibble(zx_y = 1) sp <- build_longer_spec(df, zx_y, names_to = c("a", "b"), names_pattern = "z(.)_(.)") expect_equal(sp$a, "x") expect_equal(sp$b, "y") sp <- build_longer_spec(df, zx_y, names_to = "a", names_pattern = "z(.)") expect_equal(sp$a, "x") }) test_that("names_to can override value_to", { df <- tibble(x_y = 1) sp <- build_longer_spec(df, x_y, names_to = c("a", ".value"), names_sep = "_") expect_equal(sp$.value, "y") }) test_that("names_prefix strips off from beginning", { df <- tibble(zzyz = 1) sp <- build_longer_spec(df, zzyz, names_prefix = "z") expect_equal(sp$name, "zyz") }) test_that("can cast to custom type", { df <- tibble(w1 = 1) sp <- build_longer_spec(df, w1, names_prefix = "w", names_transform = list(name = as.integer) ) expect_equal(sp$name, 1L) }) test_that("transform is applied before cast (#1233)", { df <- tibble(w1 = 1) sp <- build_longer_spec( df, w1, names_prefix = "w", names_ptypes = list(name = integer()), names_transform = list(name = as.numeric) ) expect_identical(sp$name, 1L) }) test_that("`names_ptypes` and `names_transform` work with single values (#1284)", { df <- tibble(`1x2` = 1) res <- build_longer_spec( data = df, cols = `1x2`, names_to = c("one", "two"), names_sep = "x", names_transform = as.numeric ) expect_identical(res$one, 1) expect_identical(res$two, 2) res <- build_longer_spec( data = df, cols = `1x2`, names_to = c("one", "two"), names_sep = "x", names_transform = as.numeric, names_ptypes = integer() ) expect_identical(res$one, 1L) expect_identical(res$two, 2L) }) test_that("`names_ptypes = list()` is interpreted as recycling for all name columns (#1296)", { df <- tibble(`1x2` = 1) res <- build_longer_spec( data = df, cols = `1x2`, names_to = c("one", "two"), names_sep = "x", names_transform = as.list, names_ptypes = list() ) expect_identical(res$one, list("1")) expect_identical(res$two, list("2")) }) test_that("`values_ptypes` works with single empty ptypes (#1284)", { df <- tibble(x_1 = 1, y_1 = 2) res <- pivot_longer( data = df, cols = everything(), names_to = c(".value", "set"), names_sep = "_", values_ptypes = integer() ) expect_identical(res$x, 1L) expect_identical(res$y, 2L) }) test_that("`values_ptypes = list()` is interpreted as recycling for all value columns (#1296)", { df <- tibble(x_1 = list_of(1L, 2:3, 4L), y_1 = list_of(2:3, 4L, 5:6)) res <- pivot_longer( data = df, cols = everything(), names_to = c(".value", "set"), names_sep = "_", values_ptypes = list() ) expect_identical(res$x, vec_cast(df$x_1, list())) expect_identical(res$y, vec_cast(df$y_1, list())) }) test_that("`values_transform` works with single functions (#1284)", { df <- tibble(x_1 = 1, y_1 = 2) res <- pivot_longer( data = df, cols = everything(), names_to = c(".value", "set"), names_sep = "_", values_transform = as.character ) expect_identical(res$x, "1") expect_identical(res$y, "2") }) test_that("Error if the `col` can't be selected.", { expect_snapshot({ (expect_error(pivot_longer(iris, matches("foo")))) }) }) test_that("named `cols` gives clear error (#1104)", { df <- data.frame(x = 1, y = 2) expect_snapshot(pivot_longer(df, c(z = y)), error = TRUE) }) test_that("`names_to` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(build_longer_spec(df, x, names_to = 1))) (expect_error(build_longer_spec(df, x, names_to = c("x", "y")))) (expect_error(build_longer_spec(df, x, names_to = c("x", "y"), names_sep = "_", names_pattern = "x"))) }) }) test_that("`names_ptypes` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(build_longer_spec(df, x, names_ptypes = 1))) (expect_error(build_longer_spec(df, x, names_ptypes = list(integer())))) }) }) test_that("`names_transform` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(build_longer_spec(df, x, names_transform = 1))) (expect_error(build_longer_spec(df, x, names_transform = list(~.x)))) }) }) test_that("`values_ptypes` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(pivot_longer(df, x, values_ptypes = 1))) (expect_error(pivot_longer(df, x, values_ptypes = list(integer())))) }) }) test_that("`values_transform` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(pivot_longer(df, x, values_transform = 1))) (expect_error(pivot_longer(df, x, values_transform = list(~.x)))) }) }) test_that("`cols_vary` is validated", { df <- tibble(x = 1) expect_snapshot({ (expect_error(pivot_longer(df, x, cols_vary = "fast"))) (expect_error(pivot_longer(df, x, cols_vary = 1))) }) }) test_that("`pivot_longer()` catches unused input passed through the dots", { df <- tibble(id = c("a", "b"), x = c(1, 2), y = c(3, 4)) expect_snapshot({ (expect_error(pivot_longer(df, c(x, y), 1))) (expect_error(pivot_longer(df, c(x, y), col_vary = "slowest"))) }) }) test_that("`build_longer_spec()` requires empty dots", { df <- tibble(id = c("a", "b"), x = c(1, 2), y = c(3, 4)) expect_snapshot({ (expect_error(build_longer_spec(df, c(x, y), 1))) (expect_error(build_longer_spec(df, c(x, y), name_to = "name"))) }) }) test_that("`pivot_longer_spec()` requires empty dots", { df <- tibble(id = c("a", "b"), x = c(1, 2), y = c(3, 4)) spec <- build_longer_spec(df, c(x, y)) expect_snapshot({ (expect_error(pivot_longer_spec(df, spec, 1))) (expect_error(pivot_longer_spec(df, spec, col_vary = "slowest"))) }) })