【问题标题】:Changing multiple Columns in data.table r更改 data.table r 中的多个列
【发布时间】:2015-07-28 10:23:05
【问题描述】:

我正在寻找一种方法来操作 R 中 data.table 中的多个列。由于我必须动态处理列以及第二个输入,因此我无法找到答案。

这个想法是通过将所有值除以日期值来索引某个日期的两个或多个系列,例如:

set.seed(132)
# simulate some data
dt <- data.table(date = seq(from = as.Date("2000-01-01"), by = "days", length.out = 10),
                 X1 = cumsum(rnorm(10)),
                 X2 = cumsum(rnorm(10)))

# set a date for the index
indexDate <- as.Date("2000-01-05")

# get the column names to be able to select the columns dynamically
cols <- colnames(dt)
cols <- cols[substr(cols, 1, 1) == "X"]

第 1 部分:简单的 data.frame/apply 方法

df <- as.data.frame(dt)
# get the right rownumber for the indexDate
rownum <- max((1:nrow(df))*(df$date==indexDate))

# use apply to iterate over all columns
df[, cols] <- apply(df[, cols], 
                    2, 
                    function(x, i){x / x[i]}, i = rownum)

第 2 部分:(快速)data.table 方法 到目前为止,我的 data.table 方法如下所示:

for(nam in cols) {
  div <- as.numeric(dt[rownum, nam, with = FALSE])
  dt[ , 
     nam := dt[,nam, with = FALSE] / div,
     with=FALSE]
}

尤其是所有with = FALSE 看起来不太像data.table。

您知道执行此操作的更快/更优雅的方法吗?

非常感谢任何想法!

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    跟进您的代码和 akrun 给出的答案,我建议您使用 .SDcols 提取数字列并使用 lapply 循环它们。以下是我的做法:

    index <-as.Date("2000-01-05")
    
    rownum<-max((dt$date==index)*(1:nrow(dt)))
    
    dt[, lapply(.SD, function (i) i/i[rownum]), .SDcols = is.numeric]
    

    如果您有大量的数字列并且您想对所有列应用这种除法,那么使用 .SDcols 可能特别有用。

    【讨论】:

      【解决方案2】:

      一种选择是使用set,因为这涉及多个列。使用set 的好处是可以避免[.data.table 的开销,速度更快。

      library(data.table)
      for(j in cols){
        set(dt, i=NULL, j=j, value= dt[[j]]/dt[[j]][rownum])
      }
      

      或者稍微慢一点的选择是

      dt[, (cols) :=lapply(.SD, function(x) x/x[rownum]), .SDcols=cols]
      

      【讨论】:

        猜你喜欢
        • 2016-07-20
        • 2015-05-04
        • 1970-01-01
        • 2015-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多