jea*_*ain 10 r data.table
我正在尝试做一个简单的事情,按照它们的平均值划分40列data.table.我无法提供实际数据(并非所有列都是数字,我有> 8M行),但这是一个例子:
library(data.table)
dt <- data.table(matrix(sample(1:100,4000,T),ncol=40))
colmeans <- colMeans(dt)
Run Code Online (Sandbox Code Playgroud)
接下来我以为我会这样做:
for (col in names(colmeans)) dt[,col:=dt[,col]/colmeans[col]]
Run Code Online (Sandbox Code Playgroud)
但是这会返回一个错误,因为dt[,col]要求不引用列名.使用as.name(col)不削减它.现在,
res <- t(t(dt[,1:40,with=F]/colmeans))
Run Code Online (Sandbox Code Playgroud)
包含扩展结果,但我无法将其插回到data.table中,如
dt[,1:40] <- res
Run Code Online (Sandbox Code Playgroud)
不起作用,也不起作用dt[,1:40:=res, with=F].
以下作品,但我发现它很难看:
for (i in seq_along(colmeans)) dt[,i:=dt[,i,with=F]/colmeans[i],with=F]
Run Code Online (Sandbox Code Playgroud)
当然,我也可以重新通过调用一个新的data.table data.table()上res和其他非数值列我data.table有,但不是自己的东西更有效率?
tal*_*lat 26
怎么样
dt[, (names(dt)) := lapply(.SD, function(x) x/mean(x))]
Run Code Online (Sandbox Code Playgroud)
如果需要指定某些列,可以使用
dt[, 1:40 := lapply(.SD, function(x) x/mean(x)), .SDcols = 1:40]
Run Code Online (Sandbox Code Playgroud)
要么
cols <- names(dt)[c(1,5,10)]
dt[, (cols) := lapply(.SD, function(x) x/mean(x)), .SDcols = cols]
Run Code Online (Sandbox Code Playgroud)
我们也可以使用set. [.data.table在这种情况下,使用with应该没有明显的区别:=,但在[.data.table必须多次调用的情况下,使用set()有助于避免这种开销并且可以明显更快。
for(j in names(dt)) {
set(dt, i=NULL, j = j, value = dt[[j]]/mean(dt[[j]]))
}
Run Code Online (Sandbox Code Playgroud)
也可以在选定的列上完成,即
nm1 <- names(dt)[1:5]
for(j in nm1){
set(dt, i = NULL, j = j, value = dt[[j]]/mean(dt[[j]]))
}
Run Code Online (Sandbox Code Playgroud)
set.seed(24)
dt <- as.data.frame(matrix(sample(1:100,4000,TRUE),ncol=40))
setDT(dt)
Run Code Online (Sandbox Code Playgroud)