Skip to content

Commit

Permalink
Add "which" to filtering verbs (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
asardaes committed Jul 6, 2019
1 parent 7cf3d68 commit 247fc6f
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 15 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- `distinct` gained `.keep_all` and `.keep_old` parameters.
- `filter_on` now allows empty names for data tables that already have keys (#17).
- All filtering verbs now have a `which` parameter (#17).

# table.express 0.2.0

Expand Down
10 changes: 6 additions & 4 deletions R/VERBS-filter_on.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
#' Helper to filter specifying the `on` part of the [data.table::data.table] query.
#'
#' @export
#' @importFrom rlang abort
#' @importFrom rlang expr
#'
#' @template data-arg
#' @param ... Key-value pairs, maybe with empty keys if the `data.table` already has them. See
#' details.
#' @param nomatch,mult See [data.table::data.table].
#' @param which,nomatch,mult See [data.table::data.table].
#' @param .negate Whether to negate the expression and search only for rows that don't contain the
#' given values.
#' @template chain-arg
Expand All @@ -32,8 +31,8 @@
#' start_expr %>%
#' filter_on(cyl = 4, gear = 5)
#'
filter_on <- function(.data, ..., nomatch = getOption("datatable.nomatch"), mult = "all", .negate = FALSE,
.chain = getOption("table.express.chain", TRUE))
filter_on <- function(.data, ..., which = FALSE, nomatch = getOption("datatable.nomatch"), mult = "all",
.negate = FALSE, .chain = getOption("table.express.chain", TRUE))
{
key_value <- parse_dots(FALSE, ...)
keys <- names(key_value)
Expand All @@ -49,6 +48,9 @@ filter_on <- function(.data, ..., nomatch = getOption("datatable.nomatch"), mult
if (all(nzchar(keys))) {
frame_append(ans, on = !!keys, .parse = FALSE)
}
if (!missing(which)) {
frame_append(ans, which = !!which, .parse = FALSE)
}
if (!missing(nomatch)) {
frame_append(ans, nomatch = !!nomatch, .parse = FALSE)
}
Expand Down
7 changes: 5 additions & 2 deletions R/VERBS-filter_sd.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#' @importFrom rlang enexpr
#' @importFrom rlang enquo
#' @importFrom rlang expr
#' @importFrom rlang maybe_missing
#' @importFrom rlang syms
#' @importFrom rlang zap
#'
#' @template data-arg
#' @param .SDcols See [data.table::data.table] and the details here.
#' @param .how The filtering function or predicate.
#' @param ... Possibly more arguments for `.how`.
#' @param which Passed to [data.table::data.table].
#' @param .collapse See [where-table.express].
#' @template parse-arg
#' @template chain-arg
Expand All @@ -37,7 +39,7 @@
#' start_expr %>%
#' filter_sd(c("vs", "am"), .COL == 1)
#'
filter_sd <- function(.data, .SDcols, .how = Negate(is.na), ..., .collapse = `&`,
filter_sd <- function(.data, .SDcols, .how = Negate(is.na), ..., which, .collapse = `&`,
.parse = getOption("table.express.parse", FALSE),
.chain = getOption("table.express.chain", TRUE))
{
Expand All @@ -58,7 +60,8 @@ filter_sd <- function(.data, .SDcols, .how = Negate(is.na), ..., .collapse = `&`

clauses <- Map(substitue_col_pronoun, list(.how), rlang::syms(.SDcols))

where(.data, !!!clauses, .collapse = !!rlang::enexpr(.collapse), .parse = FALSE, .chain = .chain)
where(.data, !!!clauses, which = rlang::maybe_missing(which), .collapse = !!rlang::enexpr(.collapse),
.parse = FALSE, .chain = .chain)
}

#' @importFrom rlang as_label
Expand Down
11 changes: 9 additions & 2 deletions R/VERBS-where.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ where <- function(.data, ...) {
#' @rdname where-table.express
#' @export
#' @importFrom rlang enquo
#' @importFrom rlang is_missing
#' @importFrom rlang quo_get_expr
#'
#' @param which Passed to [data.table::data.table].
#' @param .collapse A boolean function which will be used to "concatenate" all conditions in `...`.
#' @template parse-arg
#' @template chain-arg
Expand All @@ -32,7 +34,7 @@ where <- function(.data, ...) {
#' start_expr %>%
#' where(vs == 0, am == 1)
#'
where.ExprBuilder <- function(.data, ..., .collapse = `&`,
where.ExprBuilder <- function(.data, ..., which = FALSE, .collapse = `&`,
.parse = getOption("table.express.parse", FALSE),
.chain = getOption("table.express.chain", TRUE))
{
Expand All @@ -52,5 +54,10 @@ where.ExprBuilder <- function(.data, ..., .collapse = `&`,
clause <- reduce_expr(clause[-1L], first_where, .collapse, .parse = .parse)
}

.data$set_where(clause, .chain)
.data <- .data$set_where(clause, .chain)
if (!rlang::is_missing(which)) {
frame_append(.data, which = !!which, .parse = FALSE)
}

.data
}
1 change: 1 addition & 0 deletions inst/NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

- `distinct` gained `.keep_all` and `.keep_old` parameters.
- `filter_on` now allows empty names for data tables that already have keys.
- All filtering verbs now have a `which` parameter.
8 changes: 4 additions & 4 deletions man/filter_on.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions man/filter_sd.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion man/where-table.express.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions tests/testthat/unit/test-filter.R
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,9 @@ test_that("The filter verb works with several values per key for primary keys.",

expect_identical(ans, expected)
})

test_that("Filtering when passing which = TRUE works.", {
expected <- DT[cyl == 6 & mpg > 20, which = TRUE]
ans <- DT %>% start_expr %>% filter(cyl == 6, mpg > 20, which = TRUE) %>% end_expr
expect_identical(ans, expected)
})
6 changes: 6 additions & 0 deletions tests/testthat/unit/test-filter_on.R
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ test_that("The filter_on verb works for several values per key.", {

expect_identical(ans, expected)
})

test_that("The filter_on verb works when which = TRUE.", {
expected <- data.table::copy(DT)[.(1, 0), on = c("vs", "am"), which = TRUE]
ans <- DT %>% start_expr %>% filter_on(vs = 1, am = 0, which = TRUE) %>% end_expr(.by_ref = FALSE)
expect_identical(ans, expected)
})
6 changes: 6 additions & 0 deletions tests/testthat/unit/test-filter_sd.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,9 @@ test_that("Filtering SD with :-calls works.", {
ans <- DT %>% start_expr %>% filter_sd(vs:9, .COL == 1) %>% end_expr
expect_identical(ans, expected)
})

test_that("Filtering SD when which = TRUE works.", {
expected <- DT[vs == 1 & am == 1, which = TRUE]
ans <- DT %>% start_expr %>% filter_sd(vs:am, .COL == 1, which = TRUE) %>% end_expr
expect_identical(ans, expected)
})

0 comments on commit 247fc6f

Please sign in to comment.