【发布时间】:2020-07-18 20:32:33
【问题描述】:
我有一个非常大的 data.table,有 1.6x10^8 行,我想在 exposure 和 exposure.before.index 列之间执行逐行操作,如下面的示例所示。
我创建了 TI 列(即治疗强化),它指示一个非 ID 当前是否在一种或多种药物上,exposure,这与它们在每个 ID 各自第一行的任何药物不同,exposure.before.index。您可以查看我的代码并观察最终输出是否如说明的那样。
library(data.table)
DT <- data.table::data.table(ID=c("a","a","a","b","b","c","c"),
drugA=c(1,1,1,0,0,0,0),
drugB=c(0,1,1,1,0,0,0),
drugC=c(0,0,1,0,1,0,0))
DT[, exposure := gsub("NA\\+|\\+NA", "", do.call(paste,
c(Map(function(x, y) names(.SD)[(NA^!x) * y], .SD,
seq_along(.SD)), sep="+"))), .SDcols = drugA:drugC]
DT[exposure=="NA",exposure:="NONE"]
DT[,exposure.before.index:=c("drugA","drugA","drugA","drugB","drugB","NONE","NONE")]
DT[,CNT:=1:.N]
DT[!(exposure.before.index!="NONE" & exposure=="NONE"),TI:=(any(!unlist(strsplit(exposure, "[+]"))%in%unlist(strsplit(exposure.before.index, "[+]")))),by="CNT"]
DT[is.na(TI),TI:=FALSE]
DT
ID drugA drugB drugC exposure exposure.before.index CNT TI
1: a 1 0 0 drugA drugA 1 FALSE
2: a 1 1 0 drugA+drugB drugA 2 TRUE
3: a 1 1 1 drugA+drugB+drugC drugA 3 TRUE
4: b 0 1 0 drugB drugB 4 FALSE
5: b 0 0 1 drugC drugB 5 TRUE
6: c 0 0 0 NONE NONE 6 FALSE
7: c 0 0 0 NONE NONE 7 FALSE
我创建 CNT 是为了在 exposure 和 exposure.before.index 之间应用我的函数 any(!unlist(strsplit(exposure, "[+]"))%in%unlist(strsplit(exposure.before.index, "[+]")))。由于我使用此方法的 1.6x10^8 行需要相当长的时间。当我想逐行应用某个操作/函数时,我通常会使用这种 data.table[...,by="CNT"] 技术,但我发现这对于非常大的 data.table 来说并不可靠。你们中的一些人还有其他方法比我的方法更强大吗?
我发现了与我的主题类似的其他问题,但答案并未概括为以稳健的方式对用户定义的函数应用逐行操作。
感谢任何帮助和/或建议。
【问题讨论】:
-
嗨 theneil,你能解释一下整数列的含义吗?是否所有药物都以整数列编码?在第 2 行
exposure.before.index = "drugA",但在您的文字中,您声明“与他们之前使用的任何药物不同,exposure.before.index”。你能澄清一下吗?一般来说,字符串操作很慢,所以如果你能将你的问题简化为整数或逻辑比较,你会好很多。 -
@IanCampbell 你发现了一个错误。所以
exposure.before.index应该包含患者在第一行使用的药物。在尝试撰写此专栏时,我随机选择了药物类型,并专注于所需的输出,而不是遵循我原来的工作 data.table 中的逻辑。我现在正在编辑;希望它更有意义 -
您能否确认
drugA、drugB和drugC是否在您的数据集中实际可用,或者它们是否只是为了在此处创建数据集而存在?如果是后者,我建议删除它们以仅包含您的实际数据集的样子。 -
@Cole 我的实际数据集按通用名称有超过 15 种不同的药物类别。包括药物的实际名称是大材小用;我创建了这个示例,以便我可以在我的实际数据集上重现它,而不管药物名称是什么。我刚刚看到你发布了一个答案。我将在当天晚些时候彻底讨论它。谢谢!!
-
抱歉,不是命名约定,而是字段本身。如果有的话,我会将名称缩短为 A、B、C。
标签: r data.table robust rowwise