我有一个巨大的数据集,有200多万个数据集和100列。有9列包含ICD-10疾病代码,每个列以不同的字母开头。
例如:
icd1 <- c("O230", "B540", "D990", "Y555", "E980", "J777", "P090", "Q090", "R433")
icd2 <- c("O230", "B540", "D990", "Y555", "E980", "J777", "P090", "Q090", "Z433")
icd3 <- c("X230", "B540", "D990", "Y555", "E980", "J777", "P090", "Q090", "Z433")
data <- as.data.frame(rbind(icd1, icd2, icd3))我需要做的是创建一个名为"ICD_Z“的新列,检查这9个ICD-10列的每一个代码,看看它们中是否有一个以字母Z开头,所以如果是这样的话,我创建的列将收到1,否则,0。但只有当这9列都没有以字母O开头的ICD-10代码时,它才能接收到1。
所以我的输出应该是这样的:

我怎么能这么做?
发布于 2022-05-25 22:25:45
你可以用if_any和if_all
data %>%
mutate(ICD_Z = if_any(V1:V9, ~grepl('^Z', .)) *
if_all(V1:V9, ~!grepl('^O', .)))
V1 V2 V3 V4 V5 V6 V7 V8 V9 ICD_Z
icd1 O230 B540 D990 Y555 E980 J777 P090 Q090 R433 0
icd2 O230 B540 D990 Y555 E980 J777 P090 Q090 Z433 0
icd3 X230 B540 D990 Y555 E980 J777 P090 Q090 Z433 1编辑:
可以使用变量存储有关列的位置:
nms <- c(1,2,3,5,7,8)
data %>%
mutate(ICD_Z = if_any(all_of(nms), ~grepl('^Z', .)) *
if_all(all_of(nms), ~!grepl('^O', .)))发布于 2022-05-25 22:09:14
更新:一种更快的方法:
icd_cols = paste0("V",1:9)
f <- function(v) !any(v=="O") & any(v=="Z")
setDT(data)
set(data, j="icdz", value= apply(data[,..icd_cols],1,\(i) f(substr(i,1,1))))原解
对于您的大型数据集,您可以使用这种使用data.table的方法提高一些速度。在3行的小例子中,我非正式地发现这大约快了5倍。
icd_cols = colnames(data)[c(20,21,37:45)]
icd_cols = paste0("V",1:9)
f <- function(v) !any(v=="O") & any(v=="Z")
setDT(data)
data[, icdz:=(melt(data[,id:=.I],"id",icd_cols)[,f(substr(value,1,1)), by=id]$V1)][id:=NULL]输出:
V1 V2 V3 V4 V5 V6 V7 V8 V9 icdz
1: O230 B540 D990 Y555 E980 J777 P090 Q090 R433 FALSE
2: O230 B540 D990 Y555 E980 J777 P090 Q090 Z433 FALSE
3: X230 B540 D990 Y555 E980 J777 P090 Q090 Z433 TRUEhttps://stackoverflow.com/questions/72384414
复制相似问题