我正在尝试编写一个函数来将一些 quosure 参数传递给内部dplyr::select
。但是,我希望能够在提供参数后对它们应用一些条件。在这种特殊情况下,因为选择不存在的列会产生错误,所以我希望函数检查调用者提供的列是否存在于通过参数传递的数据帧tib
中,并在我通过 quosure 和取消引用之前删除任何不存在的列运算符到select
.
问题是,一旦某个东西在一个 quosure 中,我就不再知道如何操作它了。syms
我select
可以将名称转换为字符串,消除多余的名称,然后将字符串向量转换回符号 with ,但这基本上剥夺了使用 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