次のように2つのデータフレームがあります。それらは長さが等しくありません:
library(lubridate)
id <- c(1, 2, 2, 2, 2, 3, 4, 4, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
10, 10, 10, 11, 11, 12, 13, 14, 15, 15, 5451396, 5451396, 5451396, 5451396, 5451396)
admDt <- ymd(c("2000-02-24", "2000-04-30", "2000-06-06", "2001-01-29", "2004-06-10", "2001-05-21",
"2000-01-25", "2000-04-18", "2000-01-14", "1991-10-06", "1992-02-25", "2000-05-17",
"2003-06-06", "2009-02-16", "2000-01-23", "2000-03-10", "2000-04-05", "2000-06-16",
"2000-07-04", "2000-07-27", "2001-01-19", "2002-08-16", "2002-09-19", "2004-04-17",
"2005-08-02", "2005-09-21", "2006-07-10", "2000-02-24", "2000-05-05", "2000-08-29",
"2001-01-24", "2000-01-27", "2000-03-09", "2000-04-15", "2000-03-20", "2002-11-13",
"2000-06-28", "2000-07-02", "2000-06-13", "1999-12-27", "2008-09-10", "2000-04-09",
"2000-06-01", "2002-11-25", "2006-08-04", "2006-10-07"))
sepDt <- ymd(c("2000-02-25", "2000-05-25", "2000-06-06", "2001-02-15", "2004-07-12", "2001-06-01",
"2000-01-31", "2000-04-20", "2000-01-31", "1991-11-07", "1992-03-26", "2000-05-31",
"2003-06-17", "2009-02-23", "2000-03-06", "2000-03-17", "2000-04-06", "2000-06-28",
"2000-07-17", "2000-07-31", "2002-04-19", "2002-09-11", "2003-05-06", "2004-05-03",
"2005-08-31", "2006-05-29", "2009-06-19", "2000-03-09", "2000-05-06", "2000-09-12",
"2001-01-24", "2000-02-15", "2000-03-17", "2000-04-16", "2000-04-20", "2002-12-05",
"2000-07-27", "2000-08-15", "2000-06-22", "2000-02-12", "2008-09-17", "2000-05-26",
"2000-08-29", "2003-02-24", "2006-09-22", "2006-11-10"))
adm <- data.frame(id, admDt, sepDt)
id <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5451396)
birthDt <- ymd(c("1971-07-22", "1982-08-09", "1976-01-30", "1972-02-03", "1958-05-26", "1979-05-24",
"1971-11-03", "1980-02-05", "1978-06-08", "1969-10-14", "1962-01-01", "1977-03-09",
"1952-01-24", "1974-12-16", "1956-05-05", "1963-07-16"))
dxDt <- ymd(c("2000-02-24", "2000-04-30", "2000-03-03", "2000-01-31", "2000-06-20", "2000-12-13",
"2000-05-14", "2000-01-23", "2000-03-09", "2000-02-15", "2000-05-01", "2000-06-30",
"2000-08-15", "2000-06-22", "2000-01-27", "2000-06-01"))
admPreDx <- c("No", "No", "No", "Yes", "No", "No", "No", "No", "Yes", "Yes","Yes", "Yes", "Yes",
"Yes", "Yes", "Yes")
admPreDxNbr <- c(0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1)
admPreDxDur <- c(0, 0, 0, 6, 0, 0, 0, 0, 14, 19, 20, 2, 31, 9, 31, 25)
admPostDx <- c("Yes", "Yes", "No", "No", "No", "No", "Yes", "Yes", "No", "Yes", "No", "Yes", "No",
"No", "Yes", "Yes")
admPostDxNbr <- c(1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 3)
admPostDxDur <- c(1, 25, 0, 0, 0, 0, 14, 31, 0, 6, 0, 27, 0, 0, 16, 31)
admDx <- data.frame(id, birthDt, dxDt, admPreDx, admPreDxNbr, admPreDxDur, admPostDx, admPostDxNbr,
admPostDxDur)
> head(adm)
id admDt sepDt
1 1 2000-02-24 2000-02-25
2 2 2000-04-30 2000-05-25
3 2 2000-06-06 2000-06-06
4 2 2001-01-29 2001-02-15
5 2 2004-06-10 2004-07-12
6 3 2001-05-21 2001-06-01
> head(admDx)
id birthDt dxDt admPreDx admPreDxNbr admPreDxDur admPostDx admPostDxNbr admPostDxDur
1 1 1971-07-22 2000-02-24 No 0 0 Yes 1 1
2 2 1982-08-09 2000-04-30 No 0 0 Yes 1 25
3 3 1976-01-30 2000-03-03 No 0 0 No 0 0
4 4 1972-02-03 2000-01-31 Yes 1 6 No 0 0
5 5 1958-05-26 2000-06-20 No 0 0 No 0 0
6 6 1979-05-24 2000-12-13 No 0 0 No 0 0
実際のデータセットの範囲は 10,000 から 1,000,000+ 行です。
の各行adm
は個別の入院を表します。注:id
は患者の ID 番号、admDt
とsepDt
はそれぞれ入院日と退院日を示します。複数回入院している患者さんもいます。
の各行はadmDx
1 人の患者を表します。id
は患者の ID 番号 ( で提供されているものと一致adm
) であり、birthDt
とdxDt
はそれぞれ患者の生年月日と診断日です。
私はいくつかの縦断的/時系列分析を行っており、診断前と診断後の異なる期間に患者が入院したかどうかを判断したいと考えています. 簡潔にするために、この質問は診断の前後 1 か月に関するものです。理想的には、私はしたいと思います:
- 二値変数 (「はい」/「いいえ」) を作成し、特定の患者が期間中に入院したかどうかを示します (つまり、期間の開始前に入院したか退院したかは関係ありません)。期間のオフセット後)
- 期間中に各患者が入院した回数を計算する
- 期間中に各患者が入院していた期間 (日数) を計算します。
数日間にわたって多くの投稿を確認しました (例: R 期間の重複、ID と重複する日付範囲によるデータフレームの結合、R で 2 つの日付の間に発生したイベントを表示する方法); ただし、どれも私が興味を持っている3つの側面を組み合わせているようには見えません(重複する日付間の時間の計算、複数のデータフレーム、「グループ」[または個別]による)。
私は R を初めて使用し、ループやより高度な数式の経験がほとんどありません。パッケージからfoverlaps
、lubridate
、またはを使用できるようです。ただし、関連する式を作成する方法がわかりません。%overlaps%
"DescTools"
どんな援助でも大歓迎です!
編集#1:
@sirallen の提案は、提供された例の特定の期間に有効でしたsum(pmin(dxDt, sepDt) - pmax(admDt, dxDt)), by = "id"
が、実際のデータセットでは不正確な値が返されました (たとえば、1 日に複数回入院した患者 ["2000-01-25" - "2000-01-26"]伝えられるところによると、病院で過ごした日数はゼロです. コードは同様の例に答えるために使用されているように見えるので、これは私には奇妙に思えます.この問題は、これらの患者に対していくつかの重複する日付範囲があるという事実に関連していますか?さらに, @ によって指摘されたようにsirallen、コードは、患者が期間中に1回以上の入院をしたときに強調表示しませんでした.
以下のコードは、a) 患者が入院したかどうか、および b) 入院回数を判断することで、私の質問の最初の 2 つの部分へのより直接的なルートを提供しました。
library(data.table)
setDT(adm)
setDT(admDx)[, (4:9) := NULL]
#Period bounds
admDx[, `:=`(dxDtN1 = dxDt %m-% months(1), dxDtP1 = dxDt %m+% months(1))]
#Hospitalised in the month preceding diagnosis
admDx <- adm[admDx, on = .(id, admDt < dxDt, sepDt > dxDtN1), .N, by = .EACHI]
admDx[, `:=` (admPreDx = factor(ifelse(N > 0, "Yes", "No")))]
ただし、pmin / pmax コードは引き続き機能せず、負の値が返されます。
admDx[, `:=` (birthDt = birthDt, dxDt = dxDt, dxDtN1 = dxDt %m-% months(1), dxDtP1 = dxDt %m+% months(1))]
admDx[, `:=` (admPreDxDur=as.numeric(sum(pmin(dxDt, adm$sepDt) - pmax(dxDtN1, adm$admDt)))), by = "id"]
admDx <- select(admDx, admPreDx, N, admPreDxDur)
> head(admDx)
admPreDx N admPreDxDur
1: No 0 -28573
2: No 0 -27160
3: No 0 -28366
4: Yes 1 -29357
5: No 0 -26701
6: No 0 -28044
編集#2
追加のケースをテストした後、問題 re: pmin / pmax は>
vsの使用に関連している可能性があるようです>=
:>
を使用すると、正しいDur
値が返されます。ただし、>=
を使用するとDur
、値 0 が返されます。
診断日までの日数を計算できるようにするには、このコードをどのように適用すればよいでしょうか?