Skip to content

Commit

Permalink
Silently add grouping vars whenever selecting.
Browse files Browse the repository at this point in the history
  • Loading branch information
hadley committed Mar 25, 2014
1 parent defce95 commit d39812c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 19 deletions.
10 changes: 2 additions & 8 deletions R/manip-df.r
Expand Up @@ -49,15 +49,9 @@ select.tbl_df <- function(.data, ...) {

#' @export
select.grouped_df <- function(.data, ...) {
vars <- select_vars(names(.data), ..., env = parent.frame())
vars <- select_vars(names(.data), ..., env = parent.frame(),
include = as.character(groups(.data)))

# Don't remove grouping vars!
missing <- setdiff(as.character(groups(.data)), vars)
if (length(missing) > 0) {
vars <- append(vars, structure(missing, names = missing))
warning("grouping variables added implicitely: ",
paste0(missing, collapse = ","), call. = FALSE)
}
select_impl(.data, vars)
}

Expand Down
3 changes: 2 additions & 1 deletion R/manip-grouped-dt.r
Expand Up @@ -117,7 +117,8 @@ arrange.grouped_dt <- function(.data, ...) {
#' @rdname manip_grouped_dt
#' @export
select.grouped_dt <- function(.data, ...) {
vars <- select_vars(names(.data), ..., env = parent.frame())
vars <- select_vars(names(.data), ..., env = parent.frame(),
include = as.character(groups(.data)))
out <- .data[, vars, drop = FALSE, with = FALSE]
setnames(out, names(vars))

Expand Down
3 changes: 2 additions & 1 deletion R/manip-sql.r
Expand Up @@ -12,7 +12,8 @@ arrange.tbl_sql <- function(.data, ...) {

#' @export
select.tbl_sql <- function(.data, ...) {
vars <- select_vars(tbl_vars(.data), ..., env = parent.frame())
vars <- select_vars(tbl_vars(.data), ..., env = parent.frame(),
include = as.character(groups(.data)))
# Index into variables so that select can be applied multiple times
# and after a mutate.
idx <- match(vars, tbl_vars(.data))
Expand Down
15 changes: 11 additions & 4 deletions R/manip.r
Expand Up @@ -130,6 +130,8 @@ select <- function(.data, ...) UseMethod("select")
#'
#' @param vars A character vector of existing column names.
#' @param ... Expressions to compute
#' @param include Character vector of column names that must always be
#' included in output.
#' @export
#' @keywords internal
#' @return A named character vector. Values are existing column names,
Expand All @@ -156,7 +158,7 @@ select <- function(.data, ...) UseMethod("select")
#' # Rename variables
#' select_vars(names(iris), petal_length = Petal.Length)
#' select_vars(names(iris), petal = starts_with("Petal"))
select_vars <- function(vars, ..., env = parent.frame()) {
select_vars <- function(vars, ..., env = parent.frame(), include = character()) {
args <- dots(...)
if (length(args) == 0) return(setNames(vars, vars))

Expand Down Expand Up @@ -222,10 +224,15 @@ select_vars <- function(vars, ..., env = parent.frame()) {
excl <- abs(ind[ind < 0])
incl <- incl[match(incl, excl, 0L) == 0L]

# Add variables that must be included
sel <- setNames(vars[incl], names(incl))
sel <- c(setdiff(include, sel), sel)

# Ensure all output vars named
unnamed <- names2(incl) == ""
names(incl)[unnamed] <- vars[incl][unnamed]
setNames(vars[incl], names(incl))
unnamed <- names2(sel) == ""
names(sel)[unnamed] <- sel[unnamed]

sel
}


Expand Down
9 changes: 5 additions & 4 deletions inst/tests/test-group-by.r
Expand Up @@ -139,9 +139,10 @@ test_that("original data table not modified by grouping", {
})

test_that("select(group_by(.)) implicitely adds grouping variables (#170)", {
expect_warning(
res <- group_by(mtcars, vs) %.% select(mpg) %.% summarise( mpg = mean( mpg ) )
)
expect_equal(nrow(res), 2)
res <- mtcars %.% group_by(vs) %.% select(mpg)
expect_equal(names(res), c("vs", "mpg"))

res <- mtcars %.% tbl_dt() %.% group_by(vs) %.% select(mpg)
expect_equal(names(res), c("vs", "mpg"))
})

8 changes: 7 additions & 1 deletion inst/tests/test-select.r
Expand Up @@ -64,7 +64,8 @@ test_that("num_range selects numeric ranges", {

# Data table -------------------------------------------------------------------

test_that("select changes columns in copy of data table", {dt <- data.table(x = 1:4, y = letters[1:4])
test_that("select changes columns in copy of data table", {
dt <- data.table(x = 1:4, y = letters[1:4])

expect_equal(names(select(dt, x, z = y)), c("x", "z"))
expect_equal(names(dt), c("x", "y"))
Expand Down Expand Up @@ -94,3 +95,8 @@ test_that("select renames variables (#317)", {
expect_equal(tbl_vars(first %.% select(A)), "A")
expect_equal(tbl_vars(first %.% select(B = A)), "B")
})

test_that("select preserves grouping vars", {
first <- tbls$sqlite %.% group_by(b) %.% select(a)
expect_equal(tbl_vars(first), c("b", "a"))
})

0 comments on commit d39812c

Please sign in to comment.