How can I deselect columns given in the ...
argument of a self written function. (I also need to select the columns at another point, so just specifying the columns with -
in ...
does not solve my problem.)
Any soltions are apreciated, select
-helpers, manipulating quosures
or expressions, ...
# very simple example data
test <- data.frame(a=1:3, b=1:3, c=1:3)
# function skeleton
testfun <- function(x, ...){
y <- select(x, ...)
z <- select(x, -...) # does of course not work like this
return(list(y, z)) # just as an example
}
# calling the function to select different columns
testfun(test, a)
testfun(test, a, b)
You can also drop or deselect columns by prepending the character vector of column names with the - or ! operators. For e.g., dt[, -c("col1", "col2")] or dt[, !
The most easiest way to drop columns is by using subset() function. In the code below, we are telling R to drop variables x and z. The '-' sign indicates dropping variables. Make sure the variable names would NOT be specified in quotes when using subset() function.
We can delete multiple columns in the R dataframe by assigning null values through the list() function.
These easiest solution would be to select the positive columns, and then compare names to figure out which columns to drop, as in this answer.
To work on the dots directly,
quos
).UQS
for the positive selection.c()
so that we have a vector of selection.This is the transformation described by (3) and (4).
library(dplyr)
dots <- quos(a, b)
quos(-c(UQS(dots)))
#> [[1]]
#> <quosure: frame>
#> ~-c(~a, ~b)
#>
#> attr(,"class")
#> [1] "quosures"
The full solution then would be
test <- data.frame(a = 1:3, b = 1:3, c = 1:3)
# function skeleton
testfun <- function(x, ...) {
dots <- quos(...)
y <- select(x, UQS(dots))
z <- select(x, -c(UQS(dots)))
return(list(y, z))
}
testfun(test, a)
#> [[1]]
#> a
#> 1 1
#> 2 2
#> 3 3
#>
#> [[2]]
#> b c
#> 1 1 1
#> 2 2 2
#> 3 3 3
testfun(test, a, b)
#> [[1]]
#> a b
#> 1 1 1
#> 2 2 2
#> 3 3 3
#>
#> [[2]]
#> c
#> 1 1
#> 2 2
#> 3 3
Test on selection helpers.
testfun(test, starts_with("b"), one_of("c"))
#> [[1]]
#> b c
#> 1 1 1
#> 2 2 2
#> 3 3 3
#>
#> [[2]]
#> a
#> 1 1
#> 2 2
#> 3 3
You can use this trick with purrr::modify_at
library(purrr)
testfun <- function(x, ...){
y <- select(x, ...)
z <- modify_at(x,c(...),~NULL)
return(list(y, z)) # just as an example
}
testfun(test,"a")
# [[1]]
# a
# 1 1
# 2 2
# 3 3
#
# [[2]]
# b c
# 1 1 1
# 2 2 2
# 3 3 3
What about that one?
testfun <- function(x, ...){
y <- select(x, ...)
z <- x[, !names(x) %in% names(y)]
return(list(y, z))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With