1

以前は 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

4 に答える 4

2

健康関連の研究のために SAS から R に移行したときも、同様の苦労がありました。私の解決策は、可能な限り「if...then」アプローチを手放し、R 独自のネイティブ プログラミング機能の一部を利用することでした。ここにあなたの問題への2つのアプローチがあります。

まず、インデックスを使用して要素を検索および置換できます。以下は、あなたが説明した種類の退院データです。

hosp<-read.csv(file="http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/R/sparcsShort.csv",stringsAsFactors=F)
head(hosp)

マンハッタンのすべての出生関連の診断を特定したいとします。最初に、検索基準に対して一連の TRUES と FALSE を返す論理ベクトルを作成し、次にその論理ベクトルでデータ フレームにインデックスを付けます。この場合、返される列または変数も制限しています。

myObs<-hosp$county==59 & hosp$pdx=="V3000 " #note space
myVars<-c("age", "sex", "disp")
myFile<-hosp[myObs,myVars]
head(myFile)

2 番目の、おそらくより計算的に洗練された方法は、「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)

于 2012-11-06T12:47:12.107 に答える
2

SAS での IF ... THEN >>> の動作は、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' というタイトルの本を書いています。また、Web 検索で表示される約 70 ページの長さのドラフト版も無料で入手できます。

于 2012-11-05T14:20:52.340 に答える
0

問題はicd_num数値ではないことにあると思います。

次のコマンドを使用して、この変数を作成します。

healthdemo$icd_num <- as.numeric(substr(healthdemo$ICDCODE, 2,
                                        nchar(healthdemo$ICDCODE)))

( の後の数字を消したい場合は.に置き換えas.numericas.integerください。)

次に、最初のアプローチが機能するはずです。

healthdemo$cvd[healthdemo$icd_char == 'I' &
               01 <= healthdemo$icd_num &
               healthdemo$icd_num < 52 ] <- 1
于 2012-11-05T14:27:40.037 に答える