Es wird keine Einzeiler mehr sein, aber Sie können testen, was Sie vorbei in:
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
Ich schaltete es t
-dt
da Ich mag es nicht mit die Namen der eingebauten Funktionen (wie t()
) als Variablennamen, es sei denn, ich muss wirklich. Es kann subtile Fehler in größeren Code-Blöcken einführen, die beim Debuggen frustrierend sein können.
Ich würde auch den safely()
Anruf außerhalb der f()
Funktion verschieben, um einen Funktionsaufruf jedes Mal zu speichern, wenn Sie f()
ausführen. Sie können Old-School try()
stattdessen verwenden, wenn Sie möchten, aber Sie müssen nach try-error
überprüfen, die eines Tages brechen kann. Sie könnten auch tryCatch()
wickeln, aber die safely()
Weg scheint nur sauberer für mich.
Verwenden Sie 'mget()' wie in 'dat [, mget (col)]' oder '.SD' zusammen mit '.SDcols' wie in' dat [, .SD, .SDcols = Spalten] 'wobei' Spalten = "v" '. Wenn das gleiche Funktionsargument ein Symbol (der Spalte) * und * als Zeichenvektor hat, führt dies zu Problemen und Unklarheiten. – Arun