为 data.table 的列设置多个不同的属性

Fra*_*ell 5 attributes r attr data.table

data.table具有优雅setattr的就地添加单个属性到列。有没有一种优雅的方法可以一步覆盖多个属性?例如,假设 adata.table有许多列,我想为列分配两个属性,为列分配x1三个属性,x3如下所示list

a <- list(x1=list(label='X1', units='mm'),
          x3=list(label='X3', comment='collected remotely', format='type 3'))
Run Code Online (Sandbox Code Playgroud)

我可以轻松编写处理a和调用setattr5 次的代码来完成此任务。但我希望有更好的方法。

Rui*_*das 2

我不知道下面的代码是否非常优雅,但它可以工作。这是一个双*apply循环。
引用问题:

我可以轻松地编写处理a和调用setattr5 次的代码来完成此任务。但我希望有更好的方法。

问题是nameinsetattr必须是长度为 1 的字符串,因此setattr总是需要调用 5 次。在下面的代码中,这是通过双循环伪装完成的。

该示例data.table来自DT中的第 3 个help("setattr")

library(data.table)

DT <- data.table(x1 = 1:3, y = 4:6, x3 = 7:9)
a <- list(x1=list(label='X1', units='mm'),
          x3=list(label='X3', comment='collected remotely', format='type 3'))

mapply(function(x, a){
  lapply(names(a), function(na) setattr(DT[[x]], na, a[[na]]))
}, names(a), a)

attributes(DT$x1)
#$label
#[1] "X1"
#
#$units
#[1] "mm"

attributes(DT$x3)
#$label
#[1] "X3"
#
#$comment
#[1] "collected remotely"
#
#$format
#[1] "type 3"
Run Code Online (Sandbox Code Playgroud)

笔记。为了避免循环产生丑陋的输出,请将它们包装在invisible

invisible(
  mapply(function(x, a){
    lapply(names(a), function(na) setattr(DT[[x]], na, a[[na]]))
  }, names(a), a)
)
Run Code Online (Sandbox Code Playgroud)

编辑

下面的代码更简单。

lapply(names(a), function(x){
  lapply(names(a[[x]]), function(y) setattr(DT[[x]], y, a[[x]][[y]]))
})
Run Code Online (Sandbox Code Playgroud)