Mit lapply () elegant mehrere Spalten in data.table zuweisen

Ich versuche einen eleganten Weg zu finden:= Zuweisung zum Ersetzen vieler Spalten auf einmal in adata.table durch Anwenden einer gemeinsamen Funktion. Eine typische Verwendung davon könnte darin bestehen, eine Zeichenkettenfunktion anzuwenden (z. B.gsub) auf alle Zeichenspalten einer Tabelle. Es ist nicht schwer, die zu verlängerndata.frame Art und Weise dies zu tun, um einedata.tableIch bin aber auf der Suche nach einer Methode, die mit der übereinstimmtdata.table Art und Weise Dinge zu tun.

Zum Beispiel:

library(data.table)

m <- matrix(runif(10000), nrow = 100)
df <- df1 <- df2 <- df3 <- as.data.frame(m)
dt <- as.data.table(df)
head(names(df))
head(names(dt))

## replace V20-V100 with sqrt

# data.frame approach
# by column numbers
df1[20:100] <- lapply(df1[20:100], sqrt)
# by reference to column numbers
v <- 20:100
df2[v] <- lapply(df2[v], sqrt)
# by reference to column names
n <- paste0("V", 20:100)
df3[n] <- lapply(df3[n], sqrt)

# data.table approach
# by reference to column names
n <- paste0("V", 20:100)
dt[, n] <- lapply(dt[, n, with = FALSE], sqrt)

Ich verstehe, dass es effizienter ist, eine Schleife über einen Vektor von Spaltennamen mit auszuführen:= zuweisen:

for (col in paste0("V", 20:100)) dt[, col := sqrt(dt[[col]]), with = FALSE]

Ich mag das nicht, weil ich es nicht mag, auf das zu verweisendata.table in einemj Ausdruck. Ich weiß auch, dass ich verwenden kann:= zuweisen mitlapply vorausgesetzt, ich kenne die Spaltennamen:

dt[, c("V20", "V30", "V40", "V50", "V60") := lapply(list(V20, V30, V40, V50, V60), sqrt)]

(Sie können dies erweitern, indem Sie einen Ausdruck mit unbekannten Spaltennamen erstellen.)

Im Folgenden sind die Ideen aufgeführt, die ich ausprobiert habe, aber ich konnte sie nicht zum Laufen bringen. Mache ich einen Fehler oder gibt es einen anderen Ansatz, den ich vermisse?

# possible data.table approaches?
# by reference to column names; assignment works, but not lapply
n <- paste0("V", 20:100)
dt[, n := lapply(n, sqrt), with = FALSE]
# by (smaller for example) list; lapply works, but not assignment
dt[, list(list(V20, V30, V40, V50, V60)) := lapply(list(V20, V30, V40, V50, V60), sqrt)]
# by reference to list; neither assignment nor lapply work
l <- parse(text = paste("list(", paste(paste0("V", 20:100), collapse = ", "), ")"))
dt[, eval(l) := lapply(eval(l), sqrt)]

Antworten auf die Frage(3)

Ihre Antwort auf die Frage