それはもうワンライナーではありませんが、あなたはあなたが渡している何のためにテストすることができます。
library(data.table)
library(purrr)
dat <- data.table(v="a")
f <- function(dt, x) {
# first, see if 'x' is a variable holding a string with a column name
seval <- safely(eval)
res <- seval(x, dt, parent.frame())
# if it is, then get the value, otherwise substitute() it
if ((!is.null(res$result)) && inherits(res$result, "character")) {
y <- res$result
} else {
y <- substitute(x)
}
# if it's a bare name, then we deparse it, otherwise we turn
# the string into name and then deparse it
if (inherits(y, "name")) {
y <- deparse(y)
} else if (inherits(y, "character")) {
y <- deparse(as.name(x))
}
dt[, y, with=FALSE]
}
f(dat,v)
## v
## 1: a
f(dat, "v")
## v
## 1: a
V <- "v"
f(dat, V)
## v
## 1: a
f(dat, VVV)
#> throws an Error
私が使用して好きではないので、私はdt
にt
からそれを切り替えます変数名として組み込み関数の名前(t()
のようなもの)を私が実際に持っていなければ。より大きなコードブロックに微妙なエラーが導入され、デバッグに苛立つことがあります。
f()
を実行するたびに、f()
関数の外にsafely()
呼び出しを呼び出して関数呼び出しを保存することもできます。あなたが好きなら、古い学校try()
を代わりに使うことができますが、ある日は壊れるかもしれないtry-error
を確認する必要があります。 tryCatch()
でもラップできますが、safely()
の方法はちょっときれいです。
'dat [、.SDcols = cols]'のように 'dat [、mget(col)]'や '.SD'のように' .SDcols'を使って 'cols = "v" '。同じ関数の引数に(列の)*と*を文字ベクトルとして持たせることは、問題とあいまいさを招いています。 – Arun