我正在尝试在data.table
中执行一行,但无法使其正常工作。我该怎么做?
library(data.table)
data(diamonds, package= "ggplot2")
dt <- data.table(diamonds)
# what I want, but via data.table
diamonds$sum1 <- apply(dt[,5:10, with=FALSE], 1, sum)
diamonds$sd1 <- apply(dt[,5:10, with=FALSE], 1, sd)
# why don't these work?
dt[, `:=` (sum1= sum(.SD),
sd1= sd(.SD)), .SDcols= 5:10, by= .EACHI]
dt[, `:=` (sum1= sum(dt[,5:10, with=FALSE]),
sd1= sd(dt[,5:10, with=FALSE])), by= .EACHI]
两者都给出了这个错误:
[.data.table
中的错误(dt ,,:=
(sum1 = sum(.SD),sd1 = sd(.SD)),. SDcols = 5:10,: 对象'f__'未找到
答案 0 :(得分:0)
这使用Rcpp
包来编写C ++中的快速函数,然后可以从R调用它,但我认为它相当清晰和可维护。
library(Rcpp)
cppFunction('Rcpp::NumericVector SDrowSums(Rcpp::DataFrame SD) {
Rcpp:: NumericVector sums;
for(int i = 0; i<SD.nrows(); ++i) { // each row of .SD
sums.push_back( 0.0
+ as<NumericVector>(SD[4]) [i]
+ as<NumericVector>(SD[5]) [i]
+ as<IntegerVector>(SD[6]) [i] // IntegerVector, or will be slow!
+ as<NumericVector>(SD[7]) [i]
+ as<NumericVector>(SD[8]) [i]
+ as<NumericVector>(SD[9]) [i]
);
}
return sums;
}');
dt[, "sumNew" := SDrowSums(.SD) ,by=seq_len(nrow(dt))]
最后一行为表格的每一行(SDrowSums
)调用一次函数by=seq_len(nrow(dt))
。
对我而言,大概在0.15秒内完成。不如rowSums
(对我而言为0.01),但速度与原始代码相同:diamonds$sum1 <- apply(dt[,5:10, with=FALSE], 1, sum)
。
您甚至可以替换(从零开始)列偏移(4
,5
,6
,7
,8
,{{1} })使用名称(9
,"depth"
,...)。这会减慢一点,但更具可读性。
在实践中,"table"
将为每一行调用一个SDrowSums
,但这个cpp函数更通用,允许多行SD。