Я хотел бы использовать служебную функцию, чтобы проверить, существует ли данный столбец в данном data.frame
. Я работаю в tidyverse. Лучшее, что я придумал до сих пор, это
library(magrittr)
columnExists <- function(data, col) {
tryCatch({
rlang::as_label(rlang::enquo(col)) %in% names(data)
},
error=function(e) FALSE
)
}
Это работает в глобальной среде
> mtcars %>% columnExists(mpg)
[1] TRUE
> mtcars %>% columnExists(bad)
[1] FALSE
Но не при вызове из другой функции, что является моим фактическим вариантом использования.
outerFunction <- function(d, col) {
d %>% columnExists((col))
}
> mtcars %>% outerFunction(mpg) # Expected TRUE
[1] FALSE
> mtcars %>% outerFunction(bad) # Expected FALSE
[1] FALSE
Что я делаю неправильно? Возможно ли иметь одну функцию, которая корректно работает в глобальном окружении, а также когда она вложена в другую функцию?
Я нашел несколько сообщений SO, связанных с проверкой существования данного столбца или столбцов, но все они, похоже, предполагают, что либо имя столбца будет передано в виде строки, либо вызов для проверки существования не является вложенным (или оба). Это не тот случай здесь.
@KonradRudolph Как и в моем комментарии к MrFlick, в более ранней итерации необходимо было предотвратить ошибку, когда функции передавался несуществующий столбец. Но вы правы: в этой версии это не обязательно.
Вы хотите пройти через исходный символ в вашей externalFunction. Использовать
outerFunction <- function(d, col) {
d %>% columnExists( {{col}} )
}
Синтаксис "embrace" предотвратит раннюю оценку.
Я мог бы поклясться, что пробовал это! Но я перепробовал так много комбинаций того и других, что, похоже, пропустил очевидное. Спасибо.
@Мистер Флик. Вы имеете в виду: col
будет досрочно оценен enquo()
?!
@ТарДжей. Скорее enquo
просто увидит col
, а не значение, переданное col
. Так что я не совсем правильно использую здесь «оценку», но я не уверен, как я мог бы это назвать.
Кстати, какова цель
tryCatch
? Я бы удалил это, это молча выдаст неправильный результат, если пользователь передаст фиктивный аргумент.