我之前在SAS工作,然后因学术要求而决定转到R. 我的数据(healthdemo)是包含一些健康诊断代码(ICD-10)的健康数据,我想将这些代码分成不同的列。这是str(healthdemo)的一部分:
$ PATIENT_KEY : int 7391510 7404298 7390196 7381208 7401691 7381223 7383005 10188634 7384574 7398317 ...
$ ICDCODE : Factor w/ 1125 levels "","H00","H00.0",..: 654 56 654 654 665 48 90 679 654 654 ...
$ PATIENT_ID : int 39387 50244 38388 27346 49922 27901 27867 61527 33186 45309 ...
$ DATE_OF_BIRTH : Factor w/ 14801 levels "","01/01/1000",..: 7506 10250 52 73 94 6130 85 2710 95 100 ...
ICDCODE包含许多从H00到J99的疾病;首先,我将字母与ICDCODE中的数字分开
healthdemo$icd_char = substr(healthdemo$ICDCODE,1,1)
healthdemo$icd_num = substr(healthdemo$ICDCODE,2,2)
然后我通过这个函数创建了疾病列:
healthdemo$cvd = 0
healthdemo$ihd = 0
healthdemo$mi = 0
healthdemo$dys = 0
healthdemo$afib = 0
healthdemo$chf = 0
现在我想应用一个类似于这个SAS函数的函数(我曾经使用过):
if icd_char = 'I' and 01 <= icd_num < 52 then cvd = 1;
if icd_char = 'I' and 20 <= icd_num <= 25 then ihd = 1;
if icd_char = 'I' and 21 <= icd_num <= 22 then mi = 1;
if icd_char = 'I' and 46 <= icd_num <= 49 then dys = 1;
if icd_char = 'I' and icd_num = 48 then afib = 1;
此功能将为每位患者分配给定的ICD字符和ICD编号为cvd = 1(例如)等等。
我尝试在R中使用这些功能,但它们对我不起作用:
healthdemo$cvd[healthdemo$icd_char == 'I' & 01 <= healthdemo$icd_num
& healthdemo$icd_num < 52 ] <- 1
和这个
if (healthdemo$icd_char == "I" & 01 < = healthdemo$icd_num < 52 )
{healthdemo$cvd <- 1}
有人会帮助我吗?
答案 0 :(得分:2)
IF的行为......那么&gt;&gt;&gt;在SAS中,使用NOT of if(...){...}而不是ifelse(......,...,...)来实现。而且您不能使用a < var < b
形式。此外,你还没有完全掌握R编程的功能范例。
试试这个而不是你最后的陈述:
healthdemo$cvd <- NA # initialize to missing
healthdemo$cvd <- ifelse (healthdemo$icd_char == "I" &
01 <= healthdemo$icd_num &
healthdemo$icd_num < 52 , 1, healthdemo$cvd )
请注意,表单var <- ifelse(logicalvec, value, var)
允许您进行选择性替换。旧值是默认值,逻辑向量中只有TRUE的“并行”值会触发更改。
答案 1 :(得分:2)
首先,您可以使用索引来查找和替换元素。以下是您描述的那种出院数据:
hosp<-read.csv(file="http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/R/sparcsShort.csv",stringsAsFactors=F)
head(hosp)
说我想确定曼哈顿每一个与生育有关的诊断。我首先创建一个逻辑向量,为我的搜索条件返回一系列TRUES和FALSES,然后我通过该逻辑向量索引我的数据帧。在这种情况下,我也限制我想要返回的列或变量:
myObs<-hosp$county==59 & hosp$pdx=="V3000 " #note space
myVars<-c("age", "sex", "disp")
myFile<-hosp[myObs,myVars]
head(myFile)
第二种,也许更加计算优雅的方法是使用像“grep”这样的函数。假设您有兴趣识别所有药物滥用诊断,例如酒精滥用(291,303,305和子代码),阿片类药物,大麻,安非他明,致幻剂和可卡因(304及相关子代码),或非特异性药物滥用相关诊断(292)。在SAS中,你会写出一些if-then语句(或更高效的数组):
#/*********************** SUBSTANCE ABUSE *****************/
#if pdx in /* use ICD9 codes to create diagnoses */ (’2910’,’2911’,’2912’,’2913’,’2914’,’2915’,
# ’29181’,’29189’, ’2919’,’2920’,’29211’,’29212’,’2922’,’29281’,’29282’,’29283’, #........etc....,’30592’,’30593’)
#Then subst_ab=1;
#Else subst_ab=0;
在R中,你可以写:
substance<-grep("^291[0-9,0-9]|^292[0-9,0-9]|^303[0-9,0-9]|^304[0-9,0-9]^305[0-9,0-9]", hosp$pdx)
hosp$pdx[substance]
hosp$subsAb<-"No"
hosp$subsAb[substance]<-"Yes"
hosp$subsAb[1:100]
table(hosp$subsAb)
plot(table(hosp$subsAb))
library(ggplot2)
qplot(subsAb, age,data=hosp, alpha = I(1/50))
Tomas Aragon为流行病学家撰写了一篇精彩的R介绍,详细介绍了这些方法。 (http://www.medepi.net/docs/ph251d_fall2012_epir-chap01-04.pdf)
答案 2 :(得分:0)
我认为问题是icd_num
不是数字问题。
使用以下命令创建此变量:
healthdemo$icd_num <- as.numeric(substr(healthdemo$ICDCODE, 2,
nchar(healthdemo$ICDCODE)))
(如果您想删除.
后的数字,请将as.numeric
替换为as.integer
。)
然后你的第一种方法应该有效:
healthdemo$cvd[healthdemo$icd_char == 'I' &
01 <= healthdemo$icd_num &
healthdemo$icd_num < 52 ] <- 1
答案 3 :(得分:0)
我创建了icd包来解决这类问题。您可以使用标准的疾病组,或创建自己的疾病。然后,它可以快速浏览您的所有代码并为每位患者分配疾病组。它适用于ICD-9和ICD-10代码。
我发现纯文本处理(如前一个答案中的user: 1
created -> time -> created -> time -> created -> time -> ...
)既慢又不可靠。 ICD代码在记录方式上有很多变化,例如像grep
这样的ICD-9代码相当于0919.数十万行的字符串处理对我来说太慢了,因为我使用R函数很有效,所以我用大量的C ++写了这个包,所以更大的数据用户可以在几秒钟内为一百万患者分配合并症。希望这会有所帮助。