簡體   English   中英

查找有條件的兩個日期之間的天數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM