row在data.table中应用列号引用

时间:2016-07-14 20:33:27

标签: r data.table

我正在尝试在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__'未找到

相关但不相同的问题:(1)(2)

1 个答案:

答案 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)

您甚至可以替换(从零开始)列偏移(45678,{{1} })使用名称(9"depth",...)。这会减慢一点,但更具可读性。

在实践中,"table"将为每一行调用一个SDrowSums,但这个cpp函数更通用,允许多行SD。