R 是否有一种最佳方法可以使用data.table创建一组新列?

R 是否有一种最佳方法可以使用data.table创建一组新列?,r,data.table,R,Data.table,我正在使用data.table 我有一个新列的名称向量。我想创建这些新列,但要使用旧列中的信息。 让我用下面的例子来说明: data <- data.table(a = c("OneA", "TwoB", "ThreeC"), b = c(1, 2, 3)) newCols <- c("One", "Two", "Three") for (newCol in newCols) { data[, eval(newCol) := gsub(p

我正在使用data.table 我有一个新列的名称向量。我想创建这些新列,但要使用旧列中的信息。 让我用下面的例子来说明:

data <- data.table(a = c("OneA", "TwoB", "ThreeC"),
                   b = c(1, 2, 3))

newCols <- c("One", "Two", "Three")

for (newCol in newCols) {
  data[, eval(newCol) := gsub(paste0("^.*", newCol), "", a)]
}

在本例中,我结合使用向量定义新列和使用向量值本身填充这些列。有没有更优化的方法(例如使用set())?

一种可能的方法是:

库(data.table)
DT[,(newCols):=lappy(newCols,函数(x)sub(x,“,a))[]
#>a b一二三
#>1:OneA 1,OneA,OneA
#>2:twob2 TwoB TwoB TwoB
#>3:3C 3C 3C 3C
数据


DT事实上,你离这里很近。只需将代码调整为:

for (newCol in newCols) {
  DT[, (newCol) := sub(newCol, "", a)]
}
而且您有一个既快速又节省内存的解决方案(比使用
lappy
更好)

或者,您也可以在for循环中使用
set

for (newCol in newCols) {
  set(DT, j = newCol, value = sub(newCol, "", DT[["a"]]))
}
那么,在这种情况下,为什么
for
循环是更好的选择呢

  • 使用
    lappy
    首先评估
    :=
    的RHS(右视野)。这意味着首先创建所有新列,并且必须首先在内存中分配和填充这些列,然后将它们添加到
    data.table
    for
    循环方法更有效,因为它一次只处理一列,因此只需要为该列使用工作内存
  • set
    :=
    的低开销可循环版本。它对于通过引用(使用for循环)重复更新某些列的行特别有用
    set
    消除了
    [data.table
    -方法的小开销,因此速度更快

  • 以上解释基于Matt Dowle(的创建者)和帮助文件
    ?设置

    使用
    Map()
    +
    cbind()


    谢谢!到目前为止,这是最快的解决方案me@gdol我已经解释了为什么for循环是一个好的/更好的循环choice@Jaap好久不说话了。你过得怎么样?这是一个很好的提醒来确认这两种方法之间的区别。我要刷新我的记忆。阴冷。
    for (newCol in newCols) {
      set(DT, j = newCol, value = sub(newCol, "", DT[["a"]]))
    }
    
    data <- as.data.table(c(data,`names<-`(Map(function(x) gsub(x,"",data$a),newCols),newCols)))
    
    > data
            a b    One    Two Three
    1:   OneA 1      A   OneA  OneA
    2:   TwoB 2   TwoB      B  TwoB
    3: ThreeC 3 ThreeC ThreeC     C