Skip to content

Commit

Permalink
Ignore missing names
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel- committed Nov 6, 2017
1 parent a564bf3 commit 1831a92
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 2 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* `vars_select()` and `vars_rename()` now correctly support unquoting
character vectors that have names.

* `vars_select()` now ignores missing variables.


# tidyselect 0.2.2

Expand Down
8 changes: 8 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,11 @@ is_character <- function(x, n = NULL) {

TRUE
}

are_name <- function(nms) {
if (!is_character(nms)) {
abort("Expected a character vector")
}

nms == "" | is.na(nms)
}
4 changes: 3 additions & 1 deletion R/vars-select.R
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,16 @@ is_concat_lang <- function(quo) {
vars_select_eval <- function(vars, quos) {
scoped_vars(vars)

# Peek validated variables
vars <- peek_vars()

# Overscope `c`, `:` and `-` with versions that handle strings
data_helpers <- list(`:` = vars_colon, `-` = vars_minus, `c` = vars_c)
overscope_top <- new_environment(data_helpers)

# Symbols and calls to `:` and `c()` are evaluated with data in scope
is_helper <- map_lgl(quos, quo_is_helper)
data <- set_names(as.list(seq_along(vars)), vars)
data <- data[!names(data) == ""]
overscope <- env_bury(overscope_top, !!! data)

overscope <- new_overscope(overscope, overscope_top)
Expand Down
21 changes: 20 additions & 1 deletion R/vars.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@
#' }
#' fn(starts_with("r"))
poke_vars <- function(vars) {
stopifnot(is_character(vars) || is_null(vars))
if (!is_null(vars)) {
vars <- vars_validate(vars)
}

old <- vars_env$selected
vars_env$selected <- vars
Expand Down Expand Up @@ -109,4 +111,21 @@ has_vars <- function() {
!is_null(vars_env$selected)
}

vars_validate <- function(vars) {
if (!is_character(vars)) {
abort("`vars` must be a character vector")
}

are_name <- are_name(vars)
if (any(!are_name)) {
# Propagate `type` attribute when subsetting. A proper S3 class
# might be better.
type <- attr(vars, "type")
vars <- vars[!are_name]
attr(vars, "type") <- type
}

vars
}

vars_env <- new_environment()
5 changes: 5 additions & 0 deletions tests/testthat/test-vars-pull.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ test_that("errors for bad inputs", {
fixed = TRUE
)
})

test_that("can pull variables with missing elements", {
expect_identical(vars_pull(c("a", ""), a), "a")
expect_identical(vars_pull(c("a", NA), a), "a")
})
1 change: 1 addition & 0 deletions tests/testthat/test-vars-select.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ test_that("symbol overscope works with parenthesised expressions", {

test_that("can select with unnamed elements", {
expect_identical(vars_select(c("a", ""), a), c(a = "a"))
expect_identical(vars_select(c("a", NA), a), c(a = "a"))
})

test_that("can customise error messages", {
Expand Down
8 changes: 8 additions & 0 deletions tests/testthat/test-vars.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,11 @@ test_that("has_vars() detects variables", {
scoped_vars(letters)
expect_true(has_vars())
})

test_that("Missing names are ignored", {
scoped_vars(c("foo", NA))
expect_identical(peek_vars(), "foo")

scoped_vars(c("bar", ""))
expect_identical(peek_vars(), "bar")
})

0 comments on commit 1831a92

Please sign in to comment.