【发布时间】:2013-06-01 09:21:37
【问题描述】:
我试图找出一种优雅的方式来使用:= 赋值通过应用共享函数来一次替换data.table 中的许多列。一个典型的使用可能是将字符串函数(例如,gsub)应用于表中的所有字符列。将data.frame的做事方式扩展为data.table并不难,但我正在寻找与data.table做事方式一致的方法。
例如:
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)
我知道使用 := 循环遍历列名向量来分配更有效:
for (col in paste0("V", 20:100)) dt[, col := sqrt(dt[[col]]), with = FALSE]
我不喜欢这样,因为我不喜欢在 j 表达式中引用 data.table。我也知道我可以使用:= 来分配lapply,因为我知道列名:
dt[, c("V20", "V30", "V40", "V50", "V60") := lapply(list(V20, V30, V40, V50, V60), sqrt)]
(您可以通过构建一个列名未知的表达式来扩展它。)
以下是我尝试过的想法,但我无法让它们发挥作用。我犯了一个错误,还是我错过了另一种方法?
# 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)]
【问题讨论】:
标签: r data.table