Sto cercando di trovare un modo elegante per utilizzare l'assegnazione :=
per sostituire più colonne contemporaneamente in un data.table
applicando una funzione condivisa. Un tipico utilizzo di ciò potrebbe essere l'applicazione di una funzione di stringa (ad esempio, gsub
) a tutte le colonne di caratteri in una tabella. Non è difficile estendere il modo data.frame
a un data.table
, ma sto cercando un metodo coerente con il modo di fare data.table
.Assegnazione elegante di più colonne in data.table con lapply()
Ad esempio:
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)
ho capito che è più efficiente per ciclare su un vettore di nomi di colonna che utilizzano :=
assegnare:
for (col in paste0("V", 20:100)) dt[, col := sqrt(dt[[col]]), with = FALSE]
non mi piace questo perché ho don' t come riferimento allo data.table
in un'espressione j
. So anche che posso usare :=
per assegnare con lapply
dato che so i nomi delle colonne: (. Si potrebbe estendere questo costruendo un'espressione con i nomi di colonna sconosciuti)
dt[, c("V20", "V30", "V40", "V50", "V60") := lapply(list(V20, V30, V40, V50, V60), sqrt)]
seguito sono elencate le idee Ci ho provato, ma non sono riuscito a farli funzionare. Sto commettendo un errore o c'è un altro approccio che mi manca?
# 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)]
Grazie mille per aver messo le parentesi intorno a 'col'. Fino a quando non ho ricordato quel trucco, stavo ricevendo una colonna chiamata "col". – Farrel