Условно процитируйте / подставьте выражение, если оно еще не указано
Я ищу способ процитировать аргумент, переданный функции (рассмотреть substitute()
, ggplot2
"s aes()
, subset()
или же data.table
"s [
поведение), но делайте это условно - только если еще не указано quote()
,
Это потому, что я хотел бы легко объединять функции в цепочку, которые не делают предположений о том, является ли аргумент ранее заключенным в кавычки или нет, а вместо этого заменяют его по мере необходимости.
Несколько вопросов:
- Почему это плохая идея?
- Есть ли уже какие-либо встроенные методы для достижения этой цели?
tryCatch
часть потому чтоis.language
выдает ошибку, еслиx
Обещание оценивается как неопределенная переменная. Есть ли другое / лучшее решение?
Что я придумал:
substitute_c <- function(x) {
e <- suppressWarnings(
tryCatch({x; FALSE},
error = function(e) TRUE))
if (e || !is.language(x)) {
substitute_q(substitute(x), env = parent.frame())
} else {
x
}
}
Как это устроено:
require(data.table)
require(dplyr)
# Example 1
fn <- function(x) substitute_c(x)
fn2 <- function(y) fn(substitute_c(y))
fn3 <- function(z) fn2(substitute_c(z))
fn(quote(a + b)
fn(a + b)
fn2(a + b)
fn3(quote(a + b))
# Example 2
dtcars <- mtcars %>% as.data.table
subset_test <- function(dt, cols) {
cols <- substitute_c(cols)
dt[, eval(cols)]
}
subset_test2 <- function(dt, cols) {
cols <- substitute_c(cols)
subset_test(dt, cols)
}
subset_test(dtcars, .(mpg, cyl))
subset_test(dtcars, list(mpg, cyl))
subset_test2(dtcars, .(mpg, cyl))
subset_test2(dtcars, list(mpg, cyl))