Hey there,
I have been trying a few ways to create a custom function that takes a tibble and drops the columns named in the function. I know that for select
commands you can pass the dots and select those columns, but how to unselect them?
requires(rlang)
df <- tibble(
g1 = c(1, 1, 2, 2, 2),
g2 = c(1, 2, 1, 2, 1),
a = sample(5),
b = sample(5)
)
df_output <-
df %>%
select(-g1, -g2)
my_select <- function(df, ...) {
group_sel <- enquos(...)
df %>%
select(!!!group_sel)
}
my_select(df, g1, g2)
# Works like a charm
my_second_select <- function(df, ...) {
df %>%
select(...)
}
my_second_select(df, g1, g2)
# Works too
## But for unselecting
my_unselect1 <- function(df, ...) {
group_sel <- enquos(...)
df %>%
select(-!!!group_sel)
}
my_unselect1(df, g1,g2)
#NOPE
my_unselect2 <- function(df, ...) {
df %>%
select(-...)
}
my_unselect2(df, g1,g2)
# NOPE
my_unselect3 <- function(df, ...) {
sel <- tidyselect::vars_select(tbl_vars(.data), ...)
df %>%
select(-!!!sel)
}
my_unselect3(df, g1,g2)
#NOPE
Any clues on how to do this? It seems like it should be super easy, but I can't get my head around it
joels
May 13, 2019, 8:43pm
2
I'm not sure if this is the tidyverse-approved approach, but...
In the code below, we capture the names of the columns to remove and convert them to strings with rlang::as_label()
. Now we can use select_at
with setdiff
to keep all columns except the ones provided to the function.
my_unselect <- function(df, ...) {
cols_to_remove = map_chr(enquos(...), as_label)
message("\nRemoving columns ", paste(cols_to_remove, collapse=", "), "\n")
df %>%
select_at(setdiff(names(.), cols_to_remove))
}
my_unselect(df, g1, g2)
Removing columns g1, g2
# A tibble: 5 x 2
a b
<int> <int>
1 1 5
2 4 4
3 2 3
4 5 1
5 3 2
2 Likes
cderv
May 14, 2019, 5:50am
3
Great solution ! Know that you can use ensyms
to prevent the map_chr
library(tidyverse)
df <- tibble(
g1 = c(1, 1, 2, 2, 2),
g2 = c(1, 2, 1, 2, 1),
a = sample(5),
b = sample(5)
)
my_unselect <- function(df, ...) {
cols_to_remove = ensyms(...)
message("\nRemoving columns ", paste(cols_to_remove, collapse=", "), "\n")
df %>%
# select_at(setdiff(names(.), cols_to_remove))
select_at(setdiff(names(.), cols_to_remove))
}
my_unselect(df, g1, g2)
#>
#> Removing columns g1, g2
#> # A tibble: 5 x 2
#> a b
#> <int> <int>
#> 1 5 3
#> 2 4 1
#> 3 1 5
#> 4 3 2
#> 5 2 4
Created on 2019-05-14 by the reprex package (v0.2.1.9000)
2 Likes
Thanks joels and Christophe!
1 Like
cderv
May 29, 2019, 5:48am
5
If your question's been answered, would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:
If your question has been answered, don't forget to mark the solution!
How do I mark a solution?
Find the reply you want to mark as the solution and look for the row of small gray icons at the bottom of that reply. Click the one that looks like a box with a checkmark in it:
[image]
Hovering over the mark solution button shows the label, "Select if this reply solves the problem". If you don't see the mark solution button, try clicking the three dots button ( ••• ) to expand the full set of options.
When a solution is chosen, the icon turns green and the hover label changes to: "Unselect if this reply no longer solves the problem". Success!
[solution_reply_author]
…
system
Closed
June 5, 2019, 5:48am
6
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.