我想将一个函数应用于不同的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中有太多列列,可以为每个列重复执行此操作。 我现在已经碰到了这个问题,所以任何建议都非常受欢迎。
答案 0 :(得分:1)
如果有多个群组,则一个选项是melt
数据集为{长}&#39;格式为melt
可以采用多个measure
模式
将数据集列转换为numeric
类
nm1 <- names(DT)[-1]
DT[, (nm1) := lapply(.SD, as.numeric), .SDcols = nm1]
然后melt
和dcast
这些列
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