使用 .SDcols 在 data.table 中的列子集上应用函数

Apply function across subset of columns in data.table with .SDcols

我想对 data.table 中的变量子集应用一个函数。在这种情况下,我只是更改变量类型。我可以在 data.table 中以几种不同的方式执行此操作,但是我正在寻找一种不需要中间分配的方式(本例中为 mycols)并且不需要我指定列想换两次。这是一个简化的可重现示例:

library('data.table')
n<-30
dt <- data.table(a=sample(1:5, n, replace=T),
       b=as.character(sample(seq(as.Date('2011-01-01'), as.Date('2015-01-01'), length.out=n))),
       c1235=as.character(sample(seq(as.Date('2012-01-01'), as.Date('2013-01-01'), length.out=n))),
       d7777=as.character(sample(seq(as.Date('2012-01-01'), as.Date('2013-01-01'), length.out=n)))
)

方法 1: 这行得通...但它是硬编码的

mycols <- c('b', 'c1235', 'd7777')
dt1 <- dt[,(mycols):=lapply(.SD, as.Date), .SDcols=mycols]

方法 2: 这行得通...但我需要创建一个中间对象才能使其工作 (mycols)

mycols <- which(sapply(dt, class)=='character')
dt2 <- dt[,(mycols):=lapply(.SD, as.Date), .SDcols=mycols]

方法 3: 这行得通,但我需要两次指定这个长表达式

dt3 <- dt[,(which(sapply(dt, class)=='character')):=lapply(.SD, as.Date), .SDcols=which(sapply(dt, class)=='character')]

方法 4: 这不起作用,但我想要这样的东西,它允许我只指定使 .SDcols 一次的变量。我正在寻找某种方法来用有效的东西替换 (.SD):= 或将它们链接在一起。真的,我很想知道是否有人有一种方法可以执行 WAY 1、2、3 中完成的操作,而无需指定使环境膨胀的中间分配,并且不需要两次指定相同的列。

dt3 <- dt[,(.SD):=lapply(.SD, as.Date), .SDcols=which(sapply(dt, class)=='character')]

这是一个单行答案...

for (j in  which(sapply(dt, class)=='character')) set(dt, i=NULL, j=j, value=as.Date(dt[[j]]))

这是一个问题,其中 Arun 和 Matt 各自更喜欢使用 setfor 循环而不是使用 .SD

How to apply same function to every specified column in a data.table