R:R中的SAS(if / then statement)

时间:2012-11-05 14:02:39

标签: r

我之前在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} 

有人会帮助我吗?

4 个答案:

答案 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的“并行”值会触发更改。

罗伯特•慕尼辰(Robert Muenchen)写了一本名为'R for SAS and SPSS Users'的书。还有一个免费提供的草稿版本,大约70页长,应该显示网络搜索。

答案 1 :(得分:2)

当我从SAS转向R进行与健康相关的研究时,我遇到了类似的困难。我的解决方案是尽可能地放弃“if ... then”方法并利用R的一些独特的本机编程功能。以下是解决问题的两种方法。

首先,您可以使用索引来查找和替换元素。以下是您描述的那种出院数据:

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 ++写了这个包,所以更大的数据用户可以在几秒钟内为一百万患者分配合并症。希望这会有所帮助。