1

性別、年齢、主な診断、および病院IDのレコードを含む病院訪問データがあります。これらのエントリに対して個別の変数を作成するつもりです。データにはいくつかのパターンがあります。ほとんどの観測は、性別コード(MまたはF)で始まり、年齢、診断、そして主に病院の識別子が続きます。ただし、いくつかの例外があります。一部の性同一性は01または02とコード化されており、この場合、性同一性は最後に表示されます。アーカイブを調べてgrepの例をいくつか見つけましたが、データに効率的に実装できませんでした。たとえば、コード

ndiag<-dat[grep("copd", dat[,1], fixed = TRUE),] 

各診断を個別に抽出できますが、一度にすべてを抽出することはできません。どうすればこのタスクを実行できますか?

現在の状況(列1)と私が意図しているものを含むサンプルデータを以下に示します。

diagnosis hospital  diag    age   gender
m3034CVDA   A   cvd 30-34   M
m3034cardvA A   cardv   30-34   M
f3034aceB   B   ace 30-34   F
m3034hfC    C   hf  30-34   M
m3034cereC  C   cere    30-34   M
m3034resPC  C   resp    30-34   M
3034copd_Z_01   Z   copd    30-34   M
3034copd_Z_01   Z   copd    30-34   M
fcereZ          Z   cere    NA      F
f3034respC  C   resp    30-34   F
3034copd_Z_02   Z   copd    30-34   F
4

1 に答える 1

2

この問題には2つの重要な部分があるようです。

  1. 文字列が2つの異なる方法でコード化されているという事実に対処する
  2. 文字列を適切なデータ列に接続します

注:一度に複数の値に関数を適用する場合、関数の多くはすでにベクトルを処理できます。たとえばstr_locatesubstr

パート1-m/fの文字列のクリーニング//01/02コーディング

# We will be using this library later for str_detect, str_replace, etc
library(stringr)

# first, make sure diagnosis is character (strings) and not factor (category)
diagnosis <- as.character(diagnosis)

# We will use a temporary vector, to preserve the original, but this is not a necessary step.
diagnosisTmp <- diagnosis

males <- str_locate(diagnosisTmp, "_01")
females <- str_locate(diagnosisTmp, "_02")

# NOTE: All of this will work fine as long as '_01'/'_02' appears *__only__* as gender code.
#  Therefore, we put in the next two lines to check for errors, make sure we didn't accidentally grab a "_01" from the middle of the string
#-------------------------
  if (any(str_length(diagnosisTmp) != males[,2], na.rm=T))  stop ("Error in coding for males")
  if (any(str_length(diagnosisTmp) != females[,2], na.rm=T))   stop ("Error in coding for females")
#------------------------

# remove all the '_01'/'_02'  (replacing with "")
diagnosisTmp <- str_replace(diagnosisTmp, "_01", "")
diagnosisTmp <- str_replace(diagnosisTmp, "_02", "")

# append to front of string appropriate m/f code 
diagnosisTmp[!is.na(males[,1])] <- paste0("m", diagnosisTmp[!is.na(males[,1])])
diagnosisTmp[!is.na(females[,1])] <- paste0("m", diagnosisTmp[!is.na(females[,1])])

# remove superfluous underscores
diagnosisTmp <- str_replace(diagnosisTmp, "_", "")

# display the original next to modified, for visual spot check
cbind(diagnosis, diagnosisTmp)

パート2-文字列のスプライシング

# gender is the first char, hospital is the last. 
gender <- toupper(str_sub(diagnosisTmp, 1,1))    
hosp  <- str_sub(diagnosisTmp, -1,-1) 

# age, if present is char 2-5. A warning will be shown if values are missing. Age needs to be cleaned up
age   <- as.numeric(str_sub(diagnosisTmp, 2,5))    # as.numeric will convert none-numbers to NA
age[!is.na(age)]  <- paste(substr(age[!is.na(age)], 1, 2), substr(age[!is.na(age)], 3, 4), sep="-")

# diagnosis is variable length, so we have to find where to start
diagStart <- 2 + 4*(!is.na(age))
diag  <- str_sub(diagnosisTmp, diagStart, -2)

# Put it all together into a data frame
dat <- data.frame(diagnosis, hosp, diag, age, gender)
    ## OR WITHOUT ORIGINAL DIAGNOSIS STRING ##
dat <- data.frame(hosp, diag, age, gender)
于 2012-11-18T21:41:19.623 に答える