我想遍历data.table并应用一个函数,该函数需要data.table中另一列的信息,有时甚至是多个...
让我们以mtcar为例
我觉得您可以坚持使用.SD方式,但要提供额外的参数并使之更加有效...
require(data.table)
dt = data.table(mtcars)
#looping through columns of mtcars...
cols = c('mpg', 'hp', 'disp')
dt[,lapply(.SD, function(x) x/mean(x)), .SDcols=cols]
# But actually I want to devide x by the mean of x where am==1
# Now I am doing this...
specificMean= function(DT) {
x = DT$feature
xAM = DT[AM==1]$feature
MEAN = mean(xAM, na.rm=TRUE)
x = x/MEAN
return(x)
}
dt[,(cols):=lapply(cols, function(x) specificMean(data.table(feature=get(x), AM=am))), .SDcols=cols]
print(dt)
我觉得这要慢得多,因为它在每次迭代中都执行data.table()函数...
向量化的解决方案会很好。
答案 0 :(得分:1)
一种可能的方法:
dt[, (cols) := mapply(`/`, .SD[,-"am"], lapply(.SD[am==1, -"am"], mean), SIMPLIFY=FALSE),
.SDcols=c("am", cols)]
答案 1 :(得分:0)
编辑:这似乎产生与您相同的结果。
library(data.table)
dt = data.table(mtcars)
cols = c('mpg', 'hp', 'disp')
dt[, (cols) := .SD / lapply(.SD[am == 1], mean, na.rm = TRUE), .SDcols = cols]
答案 2 :(得分:0)
system.time(dt[,lapply(cols, function(x) specificMean(data.table(feature=get(x), AM=am))), .SDcols=cols])
用户系统已使用 0.010 0.000 0.005
通过@ chinsoon12 system.time(dt[,mapply(`/`, .SD[,-"am"], lapply(.SD[am==1, -"am"], mean), SIMPLIFY=FALSE), .SDcols=c("am", cols)])
用户系统已使用 0.001 0.000 0.001
system.time(dt[,.SD / lapply(.SD[am == 1], mean, na.rm = TRUE), .SDcols = cols])
用户系统已使用 0.001 0.000 0.001