在data.table

时间:2018-01-13 15:52:09

标签: r data.table

我想将一个函数应用于不同的data.table列组,并按行进行。 例如,在下面的data.table中,如果V2和V3是一个组,而V3和V4是另一个组,我想规范化逐行组值,这样在每一行中,那些列中的值是同一组加起来为1。

library(data.table) 
set.seed(11)
DT <- data.table(V1=LETTERS[1:5],
             V2=sample(5),
             V3=sample(5),
             V4=sample(5),
             V5=sample(5))

我可以使用SDcols为一组列执行此操作,但我必须首先从整数转换为数字,因为data.table不会自动执行此操作,性能原因:

cols <- c("V2","V3")
DT[,paste0("V",2:5)] <- lapply(DT[,paste0("V",2:5)], as.numeric)
DT[, (cols):=(.SD)/sum(.SD), .SDcols=cols, by=1:nrow(DT)]

我也尝试过使用for (j in cols) set,但尽管这样做,但看起来非常笨拙。

for (j in cols) {
 set(DT, j = j, value = DT[[j]] / DT[, base::sum(.SD), .SDcols=cols, by=1:nrow(DT)][,V1]) 
}

另外,我的原始data.table中有太多列列,可以为每个列重复执行此操作。 我现在已经碰到了这个问题,所以任何建议都非常受欢迎。

1 个答案:

答案 0 :(得分:1)

如果有多个群组,则一个选项是melt数据集为{长}&#39;格式为melt可以采用多个measure模式

将数据集列转换为numeric

nm1 <- names(DT)[-1]
DT[, (nm1) := lapply(.SD, as.numeric), .SDcols = nm1]

然后meltdcast这些列

dM <- dcast(melt(DT, measure = patterns("V[2-3]", "V[4-5]"))[, 
        lapply(.SD, function(x) x/sum(x)) , V1, .SDcols = value1:value2], 
               V1~rowid(V1), value.var = c('value1', 'value2'))[, -1, with = FALSE]

并将输出分配回列

DT[, (nm1) := dM][]    
#   V1        V2        V3        V4        V5
#1:  A 0.2857143 0.7142857 0.2500000 0.7500000
#2:  B 0.5000000 0.5000000 0.5000000 0.5000000
#3:  C 0.5555556 0.4444444 0.7500000 0.2500000
#4:  D 0.6666667 0.3333333 0.4444444 0.5555556
#5:  E 0.5000000 0.5000000 0.5555556 0.4444444