[英]Find number of days between two dates with condition
我有一個像這樣的數據集 PosNeg。 我需要找到每個 ID 的第一個連續陽性之間的總天數。 連續 P 是指在第一個負數 (N) 之前的所有連續 P。
例如:對於 ID 1,第一個 P 在 2021 年 1 月 8 日,因此天數介於 01/08 和 03/026 之間。 對於 ID 2 和 3,只有 1 個連續的第一個 P,所以兩者都是 0 天。 對於 ID 4,第一個連續 P 從 2021-02-15 到 2021-03-18 開始,因此總天數為 31。
我嘗試了一些代碼,但它一次僅對一個 ID 有效,因此必須手動輸入所有 ID。 我在真實數據集中有大約 50,000 個 ID。 Python/R/SQL 中的任何建議都會有所幫助。
ID | 測試 | 日期 |
---|---|---|
1 | ñ | 2021-01-02 |
1 | 磷 | 2021-01-08 |
1 | 磷 | 2021-02-25 |
1 | 磷 | 2021-03-26 |
2 | 磷 | 2021-02-05 |
2 | ñ | 2021-03-04 |
2 | 磷 | 2021-03-30 |
3 | ñ | 2021-01-24 |
3 | 磷 | 2021-02-10 |
4 | 磷 | 2021-02-15 |
4 | 磷 | 2021-02-28 |
4 | 磷 | 2021-03-18 |
4 | ñ | 2021-04-11 |
輸出:
ID | 天 |
---|---|
1 | 77 |
2 | 0 |
3 | 0 |
4 | 31 |
您可以編寫一個只影響我們可以使用它過濾的第一個P
的函數:
fn <- function(x){
r <- rle(x)
is.na(r$values) <- which(r$values == 'P')[1]
inverse.rle(r)
}
data %>%
group_by(ID) %>%
filter(is.na(fn(Test))) %>%
summarise(days = sum(diff(as.Date(Date))))
# A tibble: 4 x 2
ID days
<int> <drtn>
1 1 77 days
2 2 0 days
3 3 0 days
4 4 31 days
如果您想要使用 Pandas 的 Python 替代方案:
import pandas as pd
# ... load as DataFrame...
df['Date'] = pd.to_datetime(df['Date'])
df['consec'] = df['Test'].ne(df['Test'].shift()).cumsum().where(df['Test'].eq('P'))
groups = df.dropna(subset='consec').groupby(['ID', 'consec'])
result = (groups.tail(1).set_index('ID')['Date'] - groups.head(1).set_index('ID')['Date']).reset_index().drop_duplicates(subset='ID')
print(result.rename(columns={'Date':'Days'}))
ID Days
0 1 77 days
1 2 0 days
3 3 0 days
4 4 31 days
library(tidyverse)
data <- tribble(
~ID, ~Test, ~Date,
1L, "N", "2021-01-02",
1L, "P", "2021-01-08",
1L, "P", "2021-02-25",
1L, "P", "2021-03-26",
2L, "P", "2021-02-05",
2L, "N", "2021-03-04",
2L, "P", "2021-03-30",
3L, "N", "2021-01-24",
3L, "P", "2021-02-10",
4L, "P", "2021-02-15",
4L, "P", "2021-02-28",
4L, "P", "2021-03-18",
4L, "N", "2021-04-11"
)
data %>%
type_convert() %>%
group_by(ID) %>%
filter(Test == "P") %>%
arrange(Date) %>%
slice(1:3) %>%
mutate(step = row_number()) %>%
pivot_wider(names_from = step, values_from = Date) %>%
summarise(Days = (`3` - `1`) %>% replace_na(as.difftime(0, units = "days")))
#>
#> ── Column specification ────────────────────────────────────────────────────────
#> cols(
#> Test = col_character(),
#> Date = col_date(format = "")
#> )
#> # A tibble: 4 × 2
#> ID Days
#> <int> <drtn>
#> 1 1 77 days
#> 2 2 0 days
#> 3 3 0 days
#> 4 4 31 days
由reprex 包於 2022-05-19 創建 (v2.0.0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.