test_that("empty slice drops all rows (#6573)", {
df <- tibble(g = c(1, 1, 2), x = 1:3)
gdf <- group_by(df, g)
rdf <- rowwise(df)
expect_identical(slice(df), df[integer(),])
expect_identical(slice(gdf), gdf[integer(),])
expect_identical(slice(rdf), rdf[integer(),])
})
test_that("slicing data.frame yields data.frame", {
df <- data.frame(x = 1:3)
expect_equal(slice(df, 1), data.frame(x = 1L))
})
test_that("slice keeps positive indices, ignoring out of range (#226)", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
out <- slice(gf, 1)
expect_equal(out$id, c(1, 2, 4))
out <- slice(gf, 2)
expect_equal(out$id, c(3, 5))
})
test_that("slice drops negative indices, ignoring out of range (#3073)", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
out <- slice(gf, -1)
expect_equal(out$id, c(3, 5, 6))
out <- slice(gf, -(1:2))
expect_equal(out$id, 6)
})
test_that("slice errors if positive and negative indices mixed", {
expect_snapshot(error = TRUE, {
slice(tibble(), 1, -1)
})
})
test_that("slice ignores 0 and NA (#3313, #1235)", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
out <- slice(gf, 0)
expect_equal(out$id, integer())
out <- slice(gf, 0, 1)
expect_equal(out$id, c(1, 2, 4))
out <- slice(gf, NA)
expect_equal(out$id, integer())
out <- slice(gf, NA, -1)
expect_equal(out$id, c(3, 5, 6))
})
test_that("slicing with one-column matrix is deprecated", {
df <- tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6)
expect_snapshot({
out <- slice(df, matrix(c(1, 3)))
})
expect_equal(out$id, c(1, 3))
})
test_that("slice errors if index is not numeric", {
expect_snapshot(error = TRUE, {
slice(tibble(), "a")
})
})
test_that("slice preserves groups iff requested", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
out <- slice(gf, 2, 3)
expect_equal(group_keys(out), tibble(g = c(2, 3)))
expect_equal(group_rows(out), list_of(1, c(2, 3)))
out <- slice(gf, 2, 3, .preserve = TRUE)
expect_equal(group_keys(out), tibble(g = c(1, 2, 3)))
expect_equal(group_rows(out), list_of(integer(), 1, c(2, 3)))
})
test_that("slice handles zero-row and zero-column inputs (#1219, #2490)", {
df <- tibble(x = numeric())
expect_equal(slice(df, 1), df)
df <- tibble(.rows = 10)
expect_equal(slice(df, 1), tibble(.rows = 1))
})
test_that("user errors are correctly labelled", {
df <- tibble(x = 1:3)
expect_snapshot(error = TRUE, {
slice(df, 1 + "")
slice(group_by(df, x), 1 + "")
})
})
test_that("`...` can't be named (#6554)", {
df <- tibble(g = 1, x = 1)
expect_snapshot(error = TRUE, {
slice(df, 1, foo = g)
})
})
test_that("slice keeps zero length groups", {
df <- tibble(
e = 1,
f = factor(c(1, 1, 2, 2), levels = 1:3),
g = c(1, 1, 2, 2),
x = c(1, 2, 1, 4)
)
df <- group_by(df, e, f, g, .drop = FALSE)
expect_equal(group_size(slice(df, 1)), c(1, 1, 0) )
})
test_that("slicing retains labels for zero length groups", {
df <- tibble(
e = 1,
f = factor(c(1, 1, 2, 2), levels = 1:3),
g = c(1, 1, 2, 2),
x = c(1, 2, 1, 4)
)
df <- group_by(df, e, f, g, .drop = FALSE)
expect_equal(
ungroup(count(slice(df, 1))),
tibble(
e = 1,
f = factor(1:3),
g = c(1, 2, NA),
n = c(1L, 1L, 0L)
)
)
})
test_that("can group transiently using `.by`", {
df <- tibble(g = c(1, 1, 2), x = c(1, 2, 3))
out <- slice(df, n(), .by = g)
expect_identical(out$g, c(1, 2))
expect_identical(out$x, c(2, 3))
expect_s3_class(out, class(df), exact = TRUE)
})
test_that("transient grouping retains bare data.frame class", {
df <- tibble(g = c(1, 1, 2), x = c(1, 2, 3))
out <- slice(df, n(), .by = g)
expect_s3_class(out, class(df), exact = TRUE)
})
test_that("transient grouping retains data frame attributes", {
# With data.frames or tibbles
df <- data.frame(g = c(1, 1, 2), x = c(1, 2, 3))
tbl <- as_tibble(df)
attr(df, "foo") <- "bar"
attr(tbl, "foo") <- "bar"
out <- slice(df, n(), .by = g)
expect_identical(attr(out, "foo"), "bar")
out <- slice(tbl, n(), .by = g)
expect_identical(attr(out, "foo"), "bar")
})
test_that("transient grouping orders by first appearance", {
df <- tibble(g = c(2, 1, 2, 0), x = c(4, 2, 8, 5))
out <- slice(df, which(x == max(x)), .by = g)
expect_identical(out$g, c(2, 1, 0))
expect_identical(out$x, c(8, 2, 5))
})
test_that("can't use `.by` with `.preserve`", {
df <- tibble(x = 1)
expect_snapshot(error = TRUE, {
slice(df, .by = x, .preserve = TRUE)
})
})
test_that("catches `.by` with grouped-df", {
df <- tibble(x = 1)
gdf <- group_by(df, x)
expect_snapshot(error = TRUE, {
slice(gdf, .by = x)
})
})
test_that("catches `.by` with rowwise-df", {
df <- tibble(x = 1)
rdf <- rowwise(df)
expect_snapshot(error = TRUE, {
slice(rdf, .by = x)
})
})
test_that("catches `by` typo (#6647)", {
df <- tibble(x = 1)
expect_snapshot(error = TRUE, {
slice(df, by = x)
})
})
# Slice variants ----------------------------------------------------------
test_that("slice_helpers() call get_slice_size()", {
df <- tibble(x = 1)
expect_snapshot(error = TRUE, {
slice_head(df, n = "a")
slice_tail(df, n = "a")
slice_min(df, x, n = "a")
slice_max(df, x, n = "a")
slice_sample(df, n= "a")
})
})
test_that("get_slice_size() validates its inputs", {
expect_snapshot(error = TRUE, {
get_slice_size(n = 1, prop = 1)
get_slice_size(n = "a")
get_slice_size(prop = "a")
})
})
test_that("get_slice_size() snapshots", {
expect_snapshot({
body(get_slice_size(prop = 0))
body(get_slice_size(prop = 0.4))
body(get_slice_size(prop = 2))
body(get_slice_size(prop = 2, allow_outsize = TRUE))
body(get_slice_size(prop = -0.4))
body(get_slice_size(prop = -2))
body(get_slice_size(n = 0))
body(get_slice_size(n = 4))
body(get_slice_size(n = 20))
body(get_slice_size(n = 20, allow_outsize = TRUE))
body(get_slice_size(n = -4))
body(get_slice_size(n = -20))
})
})
test_that("get_slice_size() standardises prop", {
expect_equal(get_slice_size(prop = 0)(10), 0)
expect_equal(get_slice_size(prop = 0.4)(10), 4)
expect_equal(get_slice_size(prop = 2)(10), 10)
expect_equal(get_slice_size(prop = 2, allow_outsize = TRUE)(10), 20)
expect_equal(get_slice_size(prop = -0.4)(10), 6)
expect_equal(get_slice_size(prop = -2)(10), 0)
})
test_that("get_slice_size() standardises n", {
expect_equal(get_slice_size(n = 0)(10), 0)
expect_equal(get_slice_size(n = 4)(10), 4)
expect_equal(get_slice_size(n = 20)(10), 10)
expect_equal(get_slice_size(n = 20, allow_outsize = TRUE)(10), 20)
expect_equal(get_slice_size(n = -4)(10), 6)
expect_equal(get_slice_size(n = -20)(10), 0)
})
test_that("get_slice_size() rounds prop in the right direction", {
expect_equal(get_slice_size(prop = 0.16)(10), 1)
expect_equal(get_slice_size(prop = -0.16)(10), 9)
})
test_that("n must be an integer", {
df <- tibble(x = 1:5)
expect_snapshot(slice_head(df, n = 1.1), error = TRUE)
})
test_that("functions silently truncate results", {
# only test positive n because get_slice_size() converts all others
df <- tibble(x = 1:5)
expect_equal(nrow(slice_head(df, n = 6)), 5)
expect_equal(nrow(slice_tail(df, n = 6)), 5)
expect_equal(nrow(slice_min(df, x, n = 6)), 5)
expect_equal(nrow(slice_max(df, x, n = 6)), 5)
expect_equal(nrow(slice_sample(df, n = 6)), 5)
})
test_that("slice helpers with n = 0 return no rows", {
df <- tibble(x = 1:5)
expect_equal(nrow(slice_head(df, n = 0)), 0)
expect_equal(nrow(slice_tail(df, n = 0)), 0)
expect_equal(nrow(slice_min(df, x, n = 0)), 0)
expect_equal(nrow(slice_max(df, x, n = 0)), 0)
expect_equal(nrow(slice_sample(df, n = 0)), 0)
})
test_that("slice_*() doesn't look for `n` in data (#6089)", {
df <- data.frame(x = 1:10, n = 10:1, g = rep(1:2, each = 5))
expect_error(slice_max(df, order_by = n), NA)
expect_error(slice_min(df, order_by = n), NA)
expect_error(slice_sample(df, weight_by = n, n = 1L), NA)
df <- group_by(df, g)
expect_error(slice_max(df, order_by = n), NA)
expect_error(slice_min(df, order_by = n), NA)
expect_error(slice_sample(df, weight_by = n, n = 1L), NA)
})
test_that("slice_*() checks that `n=` is explicitly named and ... is empty", {
# i.e. that every function calls check_slice_dots()
df <- data.frame(x = 1:10)
expect_snapshot(error = TRUE, {
slice_head(df, 5)
slice_tail(df, 5)
slice_min(df, x, 5)
slice_max(df, x, 5)
slice_sample(df, 5)
})
# And works with namespace prefix (#6946)
expect_snapshot(error = TRUE, {
dplyr::slice_head(df, 5)
dplyr::slice_tail(df, 5)
dplyr::slice_min(df, x, 5)
dplyr::slice_max(df, x, 5)
dplyr::slice_sample(df, 5)
})
expect_snapshot(error = TRUE, {
slice_head(df, 5, 2)
slice_tail(df, 5, 2)
slice_min(df, x, 5, 2)
slice_max(df, x, 5, 2)
slice_sample(df, 5, 2)
})
})
test_that("slice_helpers do call slice() and benefit from dispatch (#6084)", {
local_methods(
slice.noisy = function(.data, ..., .preserve = FALSE) {
warning("noisy")
NextMethod()
}
)
nf <- tibble(x = 1:10, g = rep(1:2, each = 5)) %>% group_by(g)
class(nf) <- c("noisy", class(nf))
expect_warning(slice(nf, 1:2), "noisy")
expect_warning(slice_sample(nf, n = 2), "noisy")
expect_warning(slice_head(nf, n = 2), "noisy")
expect_warning(slice_tail(nf, n = 2), "noisy")
expect_warning(slice_min(nf, x, n = 2), "noisy")
expect_warning(slice_max(nf, x, n = 2), "noisy")
expect_warning(sample_n(nf, 2), "noisy")
expect_warning(sample_frac(nf, .5), "noisy")
})
test_that("slice_helper `by` errors use correct error context and correct `by_arg`", {
df <- tibble(x = 1)
gdf <- group_by(df, x)
expect_snapshot(error = TRUE, {
slice_head(gdf, n = 1, by = x)
slice_tail(gdf, n = 1, by = x)
slice_min(gdf, order_by = x, by = x)
slice_max(gdf, order_by = x, by = x)
slice_sample(gdf, n = 1, by = x)
})
})
test_that("slice_helper catches `.by` typo (#6647)", {
df <- tibble(x = 1)
expect_snapshot(error = TRUE, {
slice_head(df, n = 1, .by = x)
slice_tail(df, n = 1, .by = x)
slice_min(df, order_by = x, .by = x)
slice_max(df, order_by = x, .by = x)
slice_sample(df, n = 1, .by = x)
})
})
# slice_min/slice_max -----------------------------------------------------
test_that("min and max return ties by default", {
df <- tibble(id = 1:5, x = c(1, 1, 1, 2, 2))
expect_equal(slice_min(df, x)$id, c(1, 2, 3))
expect_equal(slice_max(df, x)$id, c(4, 5))
expect_equal(slice_min(df, x, with_ties = FALSE)$id, 1)
expect_equal(slice_max(df, x, with_ties = FALSE)$id, 4)
})
test_that("min and max reorder results", {
df <- data.frame(id = 1:4, x = c(2, 3, 1, 2))
expect_equal(slice_min(df, x, n = 2)$id, c(3, 1, 4))
expect_equal(slice_max(df, x, n = 2)$id, c(2, 1, 4))
expect_equal(slice_min(df, x, n = 2, with_ties = FALSE)$id, c(3, 1))
expect_equal(slice_max(df, x, n = 2, with_ties = FALSE)$id, c(2, 1))
})
test_that("min and max include NAs when appropriate", {
df <- tibble(id = 1:3, x = c(1, NA, NA))
expect_equal(slice_min(df, x, n = 1)$id, 1)
expect_equal(slice_max(df, x, n = 1)$id, 1)
expect_equal(slice_min(df, x, n = 2)$id, c(1, 2, 3))
expect_equal(slice_min(df, x, n = 2, with_ties = FALSE)$id, c(1, 2))
df <- tibble(id = 1:4, x = NA)
expect_equal(slice_min(df, x, n = 2, na_rm = TRUE)$id, integer())
expect_equal(slice_max(df, x, n = 2, na_rm = TRUE)$id, integer())
})
test_that("min and max ignore NA's when requested (#4826)", {
df <- tibble(id = 1:4, x = c(2, NA, 1, 2))
expect_equal(slice_min(df, x, n = 2, na_rm = TRUE)$id, c(3, 1, 4))
expect_equal(slice_max(df, x, n = 2, na_rm = TRUE)$id, c(1, 4))
# Check with list to confirm use full vctrs support
df <- tibble(id = 1:4, x = list(NULL, 1, NULL, NULL))
expect_equal(slice_min(df, x, n = 2, na_rm = TRUE)$id, 2)
expect_equal(slice_max(df, x, n = 2, na_rm = TRUE)$id, 2)
# Drop when any element is missing
df <- tibble(id = 1:3, a = c(1, 2, NA), b = c(2, NA, NA))
expect_equal(slice_min(df, tibble(a, b), n = 3, na_rm = TRUE)$id, 1)
expect_equal(slice_max(df, tibble(a, b), n = 3, na_rm = TRUE)$id, 1)
})
test_that("slice_min/max() count from back with negative n/prop", {
df <- tibble(id = 1:4, x = c(2, 3, 1, 4))
expect_equal(slice_min(df, x, n = -1), slice_min(df, x, n = 3))
expect_equal(slice_max(df, x, n = -1), slice_max(df, x, n = 3))
# and can be larger than group size
expect_equal(slice_min(df, x, n = -10), df[0, ])
expect_equal(slice_max(df, x, n = -10), df[0, ])
})
test_that("slice_min/max() can order by multiple variables (#6176)", {
df <- tibble(id = 1:4, x = 1, y = c(1, 4, 2, 3))
expect_equal(slice_min(df, tibble(x, y), n = 1)$id, 1)
expect_equal(slice_max(df, tibble(x, y), n = 1)$id, 2)
})
test_that("slice_min/max() work with `by`", {
df <- tibble(g = c(2, 2, 1, 1), x = c(1, 2, 3, 1))
expect_identical(slice_min(df, x, by = g), df[c(1, 4),])
expect_identical(slice_max(df, x, by = g), df[c(2, 3),])
})
test_that("slice_min/max() inject `with_ties` and `na_rm` (#6725)", {
# So columns named `with_ties` and `na_rm` don't mask those arguments
df <- tibble(x = c(1, 1, 2, 2), with_ties = 1:4)
expect_identical(slice_min(df, x, n = 1), vec_slice(df, 1:2))
expect_identical(slice_min(df, x, n = 1, with_ties = FALSE), vec_slice(df, 1))
expect_identical(slice_max(df, x, n = 1), vec_slice(df, 3:4))
expect_identical(slice_max(df, x, n = 1, with_ties = FALSE), vec_slice(df, 3))
df <- tibble(x = c(1, NA), na_rm = 1:2)
expect_identical(slice_min(df, x, n = 2), df)
expect_identical(slice_min(df, x, n = 2, na_rm = TRUE), vec_slice(df, 1))
expect_identical(slice_max(df, x, n = 2), df)
expect_identical(slice_max(df, x, n = 2, na_rm = TRUE), vec_slice(df, 1))
})
test_that("slice_min/max() check size of `order_by=` (#5922)", {
expect_snapshot(error = TRUE, {
slice_min(data.frame(x = 1:10), 1:6)
slice_max(data.frame(x = 1:10), 1:6)
})
})
test_that("slice_min/max() validate simple arguments", {
expect_snapshot(error = TRUE, {
slice_min(data.frame(x = 1:10))
slice_max(data.frame(x = 1:10))
slice_min(data.frame(x = 1:10), x, with_ties = 1)
slice_max(data.frame(x = 1:10), x, with_ties = 1)
slice_min(data.frame(x = 1:10), x, na_rm = 1)
slice_max(data.frame(x = 1:10), x, na_rm = 1)
})
})
# slice_sample ------------------------------------------------------------
test_that("slice_sample() respects weight_by and replaces", {
df <- tibble(x = 1:100, wt = c(1, rep(0, 99)))
out <- slice_sample(df, n = 1, weight_by = wt)
expect_equal(out$x, 1)
out <- slice_sample(df, n = 2, weight_by = wt, replace = TRUE)
expect_equal(out$x, c(1, 1))
})
test_that("slice_sample() can increase rows iff replace = TRUE", {
df <- tibble(x = 1:10)
expect_equal(nrow(slice_sample(df, n = 20, replace = FALSE)), 10)
expect_equal(nrow(slice_sample(df, n = 20, replace = TRUE)), 20)
})
test_that("slice_sample() checks size of `weight_by=` (#5922)", {
df <- tibble(x = 1:10)
expect_snapshot(slice_sample(df, n = 2, weight_by = 1:6), error = TRUE)
})
test_that("slice_sample() works with zero-row data frame (#5729)", {
df <- tibble(x = character(), w = numeric())
out <- slice_sample(df, prop = 0.5, weight_by = w)
expect_equal(out, df)
})
test_that("`slice_sample()` validates `replace`", {
df <- tibble()
expect_snapshot(error = TRUE, {
slice_sample(df, replace = 1)
slice_sample(df, replace = NA)
})
})
test_that("slice_sample() injects `replace` (#6725)", {
# So a column named `replace` doesn't mask that argument
df <- tibble(replace = 1)
expect_identical(slice_sample(df, n = 2), df)
expect_identical(slice_sample(df, n = 2, replace = TRUE), vec_slice(df, c(1, 1)))
})
test_that("slice_sample() handles positive n= and prop=", {
gf <- group_by(tibble(a = 1, b = 1), a)
expect_equal(slice_sample(gf, n = 3, replace = TRUE), gf[c(1, 1, 1), ])
expect_equal(slice_sample(gf, prop = 3, replace = TRUE), gf[c(1, 1, 1), ])
})
test_that("slice_sample() handles negative n= and prop= (#6402)", {
df <- tibble(a = 1:2)
expect_equal(nrow(slice_sample(df, n = -1)), 1)
expect_equal(nrow(slice_sample(df, prop = -0.5)), 1)
# even if larger than n
expect_equal(nrow(slice_sample(df, n = -3)), 0)
expect_equal(nrow(slice_sample(df, prop = -2)), 0)
})
test_that("slice_sample() works with `by`", {
df <- tibble(g = c(2, 2, 2, 1), x = c(1, 2, 3, 1))
expect_identical(slice_sample(df, n = 2, by = g)$g, c(2, 2, 1))
})
# slice_head/slice_tail ---------------------------------------------------
test_that("slice_head/slice_tail keep positive values", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
expect_equal(slice_head(gf, n = 1)$id, c(1, 2, 4))
expect_equal(slice_head(gf, n = 2)$id, c(1, 2, 3, 4, 5))
expect_equal(slice_tail(gf, n = 1)$id, c(1, 3, 6))
expect_equal(slice_tail(gf, n = 2)$id, c(1, 2, 3, 5, 6))
})
test_that("slice_head/tail() count from back with negative n/prop", {
df <- tibble(id = 1:4, x = c(2, 3, 1, 4))
expect_equal(slice_head(df, n = -1), slice_head(df, n = 3))
expect_equal(slice_tail(df, n = -1), slice_tail(df, n = 3))
# and can be larger than group size
expect_equal(slice_head(df, n = -10), df[0, ])
expect_equal(slice_tail(df, n = -10), df[0, ])
})
test_that("slice_head/slice_tail drop from opposite end when n/prop negative", {
gf <- group_by(tibble(g = c(1, 2, 2, 3, 3, 3), id = 1:6), g)
expect_equal(slice_head(gf, n = -1)$id, c(2, 4, 5))
expect_equal(slice_head(gf, n = -2)$id, 4)
expect_equal(slice_tail(gf, n = -1)$id, c(3, 5, 6))
expect_equal(slice_tail(gf, n = -2)$id, 6)
})
test_that("slice_head/slice_tail handle infinite n/prop", {
df <- tibble(x = 1)
expect_identical(slice_head(df, n = Inf), df)
expect_identical(slice_tail(df, n = Inf), df)
expect_identical(slice_head(df, n = -Inf), df[0, ])
expect_identical(slice_tail(df, n = -Inf), df[0, ])
expect_identical(slice_head(df, prop = Inf), df)
expect_identical(slice_tail(df, prop = Inf), df)
expect_identical(slice_head(df, prop = -Inf), df[0, ])
expect_identical(slice_tail(df, prop = -Inf), df[0, ])
})
test_that("slice_head/slice_tail work with `by`", {
df <- tibble(g = c(2, 2, 2, 1), x = c(1, 2, 3, 1))
expect_identical(slice_head(df, n = 2, by = g), df[c(1, 2, 4),])
expect_identical(slice_tail(df, n = 2, by = g), df[c(2, 3, 4),])
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.