【问题标题】:Doing j on multiple .SDcols groups in data.table对 data.table 中的多个 .SDcols 组执行 j
【发布时间】:2018-06-22 19:33:42
【问题描述】:

我想将一个函数应用于不同的 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 中有太多的列组,无法为每个列重复执行此操作。 我现在有点碰壁了,所以非常欢迎任何建议。

【问题讨论】:

  • 第二组是V4 and V5 吗?

标签: r data.table


【解决方案1】:

如果有多个组,一种选择是将melt 数据集转换为“长”格式,因为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

【讨论】:

  • 是的,就是这样,对我来说唯一的问题是我在列名中没有可辨别的模式,必须解决这个问题。
  • @novocaine 您可以将列名或索引作为list 传递,即melt(DT, measure = list(names(DT)[2:3], names(DT)[4:5]))melt(DT, measure = list(2:3,4:5))
  • 是的,我使用了列表,但是当并非所有组的列数都相同时就会出现问题
  • @novocaine 在这种情况下,将有NA 值填充,即melt(DT, measure = list(2:3,4)) sum 中有na.rm 参数要删除,即lapply(.SD, function(x) x/sum(x, na.rm = TRUE))
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2021-07-03
  • 2019-02-05
  • 1970-01-01
  • 2014-06-21
  • 2019-04-05
相关资源
最近更新 更多