2017-08-16 10 views
0

私は2つのデータフレーム、病院滞在の1つとラボ結果のもう1つを持っています。私は、どの病院が検査結果を保持しているのかを特定し、病院のデータフレームから入院と退院日を関連する検査結果の行にコピーする必要があります。2つのデータフレームからデータをリンクする効率を向上させます

私は、実験室の結果を歩くためにforループを使用しています。そして、病院の記録に一致するエントリ(患者のSSNと周囲の日付で)を探すステートメントとサブセットがあります。

これは非常に大きなデータセットであり、forループを使用すると非常に遅くなります。この種の問題をスピードアップする方法はありますか? (私はいくつかの同様の問題があるので、答えが大好きです。)

サンプルデータが追加されました。日付がラボの日付と重複しているレコードから日付を取得することを目標にして、 。この例では、患者2に病院データがなく、患者3の記録が検査日と重複しないので、得られたデータフレームは患者1の入院および退院日のみを有するべきである。

testDate <- as.Date(c("2017-01-15", "2017-01-15", "2017-01-15")) 
patientSSN <- c("1","2","3") 
labs <- data.frame(patientSSN, testDate) 

# patientSSN testDate 
# 1   1 2017-01-15 
# 2   2 2017-01-15 
# 3   3 2017-01-15 

patientSSN <- c("1","1","3","3") 
admissionDate <- as.Date(c("2017-01-07", "2017-02-01", "2016-12-01", "2017-01-16")) 
dischargeDate <- as.Date(c("2017-01-16", "2017-02-10", "2016-12-15", "2017-02-01")) 
hospitalRec <- data.frame(patientSSN, admissionDate, dischargeDate) 

for (I in 1:nrow(labs)) { 
labs[I,]$admissionDate <- hospitalRec[hospitalRec$patientSSN == labs[I,]$patientSSN & hospitalRec$admissionDate <= labs[I,]$testDate & hospitalRec$dischargeDate >= labs[I,]$testDate,]$admissionDate 

labs[I,]$admissionDate <- hospitalRec[hospitalRec$PatientSSN == labs[I,]$PatientSSN & hospitalRec$admissionDate <= labs[I,]$testDate & hospitalRec$dischargeDate >= labs[I,]$testDate,]$dischargeDate 

} 

所望のデータフレームは、次のようになります。

labs: 
    patientSSN testDate admissionDate dischargeDate 
    1   2017-01-15 2017-01-07  2017-01-16 
    2   2017-01-15 NA    NA 
    3   2017-01-15 NA    NA 

お知らせ、実際のデータでは、(部門間の放電)を修飾する複数の病院の記録の問題もあるこれらのレコードは同じを持っているでしょう入学日は異なりますが、最新のものとは異なる排出時間が重要です。しかし、最初のものは最初に... dplyr::left_joinを使用し、これはあなたのDFがどのように見えるかに似ていると仮定すると、

+3

サンプルデータを表示して、どのような出力が期待できますか?他の人があなたを適切に支援するのに役立ちます。 – Sagar

+0

'dplyr'の' join'関数を使って2つのデータフレームをマージしようとします。サンプルデータを再現すれば、それを手助けすることができます。 – sweetmusicality

+0

サンプルデータが提供されています。日付の問題を認識できないため、マージは機能しません。 – rwbuie

答えて

0

hospital_data <- data.frame(PatientSSN = c('1234567890',''), 
          admit = c('8/1/17','8/5/17'), 
          discharge = c('8/10/17','8/15/17')) 

lab_data <- data.frame(specimen_id = c('foo1','foo2','foo3','foo4','foo5','foo6','foo7'), 
         PatientSSN = c('1234567890','1234567890','1234567890','','','','8527419600'), 
         test = c('hemoglobin','inr','platelette','hemoglobin','inr','platelette','inr')) 

lab_data %>% left_join(hospital_data) 

specimen_id PatientSSN  test admit discharge 
1  foo1 1234567890 hemoglobin 8/1/17 8/10/17 
2  foo2 1234567890  inr 8/1/17 8/10/17 
3  foo3 1234567890 platelette 8/1/17 8/10/17 
4  foohemoglobin 8/5/17 8/15/17 
5  foo inr 8/5/17 8/15/17 
6  fooplatelette 8/5/17 8/15/17 
7  foo7 8527419600  inr <NA>  <NA> 

注意を(PatientSSN)あなたのid変数ということは、各テーブルで同じです。

+0

これは日付の問題を無視します。研究室には日付もあり、選択される唯一の承認日と退院日は研究室の日付を取り巻くものです。単純なマージはこれをしません(私の知識に) – rwbuie

0

OK-こちらです。しかし、ちょうどクイックヘッドアップ、しかし、訪問/アカウントに固有のID変数を持たないEMRデータで作業することはほとんどありません。私はSSNを使う前に、それをユニークな識別子として使うことにします。それにもかかわらず、これはうまくいくはずです。上記のデータを使用しました。

for(i in 1:nrow(labs)){ 

    #finding the ID (ssn) 

    ssn_match_df <- hospitalRec[which(as.character(labs$patientSSN[i]) == as.character(hospitalRec$patientSSN)),] 

    #finding record in table where the test date fall between the admit/discharge 
    ssn_match_df <- ssn_match_df[which(labs$testDate[i] >= ssn_match_df$admissionDate & 
             labs$testDate[i] <= ssn_match_df$dischargeDate),] 

    if(nrow(ssn_match_df)>0){ 
    labs[i,3] <- as.character(ssn_match_df[1,2]) 
    labs[i,4] <- as.character(ssn_match_df[1,3]) 
    } else { 
    labs[i,3] <- NA 
    labs[i,4] <- NA 
    } 


} 

colnames(labs)[3] <- 'admitDate' 
colnames(labs)[4] <- 'dischargeDate' 
+0

これは入院患者のデータフレームを一度スキャンするだけなので、これはほぼ2倍の速さでしょうか? – rwbuie

+0

それを指摘してくれてありがとう。私が見ているforループの周りには方法はありません。 SSNに関しては、患者を複数の施設に亘って照合する場合、各施設の内部識別子を使用することは好ましくありません。 – rwbuie

1

非エクイはdata.tableと、たとえば、作品に参加する:実際のデータで

library(data.table) 
setDT(labs); setDT(hospitalRec) 

labs[hospitalRec, on=.(patientSSN, testDate >= admissionDate, testDate <= dischargeDate), 
    `:=`(aDate = i.admissionDate, dDate = i.dischargeDate)] 

    patientSSN testDate  aDate  dDate 
1:   1 2017-01-15 2017-01-07 2017-01-16 
2:   2 2017-01-15  <NA>  <NA> 
3:   3 2017-01-15  <NA>  <NA> 

を、(部門間の放電)を修飾する複数の病院の記録の問題もあるこれらの記録は同じ入学日を有するが、最新のものと異なる放電時間が重要である。

hospitalRecをソートすると、上記のを追加すると効果があります。詳しくは、?data.tableを参照してください。代わりに、あなただけの並べ替え、その後

lastRec = unique(hospitalRec, by=c("patientSSN", "admissionDate"), fromLast=TRUE)) 

setorder機能がdata.tablesをソートするための標準的なツールです...のように、これらの「重複」を除く病院レコードのバージョンを作成することができます。

関連する問題