Я пытаюсь написать функцию для передачи некоторых аргументов quosure во внутреннюю область dplyr::select
.Однако я хочу иметь возможность применять некоторые условия к аргументам после их предоставления.В этом конкретном случае, поскольку выбор столбцов, которые не существуют, приводит к ошибке, я хочу, чтобы функция проверяла, существуют ли столбцы, предоставленные вызывающей стороной, в кадре данных, переданном через аргумент tib
, и удаляю те, которые не существуют, прежде чем я передамоператор quosure и unquoting для select
.
Проблема в том, что, как только что-то находится внутри выражения, я больше не знаю, как им манипулировать.Я мог бы преобразовать имена в строки, исключить лишние имена, а затем преобразовать вектор строк обратно в символы с syms
, что, я думаю, сработало бы в этом случае, потому что я отдельно передаю внутреннюю select
структуру данных, в которойЯ хочу, чтобы они были оценены, но это сводит на нет все преимущества использования quosure, а затем искусственно поставляет их снова, что кажется окольным и не элегантным.Я бы хотел избежать хитрого решения, которое работает в этом конкретном случае, но не предлагает никаких полезных принципов в следующий раз.
library(tidyverse)
tst_tb <- tibble(A = 1:10, B = 11:20, C=21:30, D = 31:40)
################################################################################
# strip() expects a non-anonymous dataframe, from which it removes the rows
# specified (as a logical vector) in remove_rows and the columns specified (as
# unquoted names) in remove_cols. It also prints a brief report; just the df
# name, length and width, and the remaining column names.
strip <- function(tib, remove_rows = FALSE, remove_cols = NULL){
remove_rows <- enquo(remove_rows)
remove_cols <- enquo(remove_cols)
tib_name <- deparse(substitute(tib))
out <- tib %>%
filter(! (!! remove_rows)) %>%
select(- !! remove_cols) %T>% (function(XX = .){
print(paste0(tib_name,": Length = ", nrow(XX), "; Width = ", ncol(XX)))
cat("\n")
cat(" Names: ", names(XX))
})
out
}
Следующая строка не будет работать из-за E
в remove_cols
аргумент.Вы должны думать о E
не как об одном имени из четырех или пяти, а как о 10 или 20 аргументах из нескольких сотен.
out_tb <- strip(tib = tst_df, remove_rows = (A < 3 | D > 36), remove_cols = c(C, D, E))
out_tb
Желаемый результат:
# A tibble: 4 x 2
A B
<int> <int>
1 3 13
2 4 14
3 5 15
4 6 16