簡體   English   中英

按 dplyr 日期之間的匯總

[英]Group by summarize in between dates with dplyr

使用匯總時,我很難理解 dplyr 中的一些邏輯。

我有興趣為每個 ID 中的每個日期計算一些感興趣的統計數據(例如,某個列的平均值),並且我有包含 start_date 和 end_date 列的數據。

假設我有分層數據,每行都有一個IDsub列,IDsub 所屬的每個更廣泛類別的ID列,一個start_date ,一個end_date和一個有意義的value

IDsub <- c("1001", "1002", "1003", "1004")
ID <- c("id1", "id1", "id2", "id2")
start_date <- as.Date(c("2021-01-01", "2021-01-02", "2021-01-05", "2021-01-10"))
end_date <- as.Date(c("2021-01-10", "2021-01-09", "2021-01-13", "2021-01-12"))
value <- c(1, 2, 2, 0)

df <- tibble(IDsub, ID, start_date, end_date, value)

原始數據如下所示:

IDsub ID    start_date end_date   value
1001  id1   2021-01-01 2021-01-10     1
1002  id1   2021-01-02 2021-01-09     2
1003  id2   2021-01-05 2021-01-13     2
1004  id2   2021-01-10 2021-01-12     0

然后我轉換數據,使其按date組織:

df1 <- df %>%
  transmute(ID, IDsub, value, date = map2(min(df$start_date), max(df$end_date), seq, by = "day")) %>%
  unnest("date")

結果如下:

ID    IDsub value   date      
id1   1001      1 2021-01-01
id1   1001      1 2021-01-02
id1   1001      1 2021-01-03
id1   1001      1 2021-01-04
...
id2   1004      0 2021-01-10
id2   1004      0 2021-01-11
id2   1004      0 2021-01-12
id2   1004      0 2021-01-13

這是我被絆倒的地方。 我想計算每個ID中每個datevalue ,但下面的代碼似乎沒有這樣做。

df2 <- df1 %>%
  group_by(ID, date) %>%
  summarize(mean(value))

前面的代碼生成以下 output:

ID    date       `mean(value)`
id1   2021-01-01           1.5
id1   2021-01-02           1.5
id1   2021-01-03           1.5
id1   2021-01-04           1.5
id1   2021-01-05           1.5

這沒有任何意義,因為 id1 的 2020-01-01 的平均值應該與 id1 的 2020-01-02 不同,因為在 2021-01-01 上只有值 = 1 的 IDsub 1001 存在,而 IDsub 1001 和值分別為 1 和 2 的 1002 都出現在 2021 年 1 月 2 日。 所以 2021-01-01 和 2021-01-02 的值應該不同,但它們不是。

我顯然在這里遺漏了一些簡單的東西。

我相信您的 map2 陳述不正確。
這是within function 中使用 lubridate 的另一個可能選項。

library(dplyr)
library(lubridate)

df <- structure(list(IDsub = c("1001", "1002", "1003", "1004"), 
                     ID = c("id1", "id1", "id2", "id2"), 
                     start_date = structure(c(18628, 18629, 18632, 18637), class = "Date"), 
                     end_date = structure(c(18637, 18636, 18640, 18639), class = "Date"), 
                     value = c(1, 2, 2, 0)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))

#find start end date and create sequence
firstdate <- min(df$start_date)
lastdate <- max(df$end_date)
timeseq <-seq(firstdate, lastdate, by="1 day")

#split by id
dflist<-split(df, df$ID)
lapply(names(dflist), function(dfname){
   
   iddf<-dflist[[dfname]]
   #create time intervals for each row 
   intervals <-interval(iddf$start_date, iddf$end_date)
   meanvalues <- sapply(timeseq, function(nrow){
      withinresult <- nrow %within% intervals
      mean(iddf$value[withinresult], na.rm=TRUE)
   })
   tibble(dfname, timeseq, meanvalues)
})

lapply語句的最終結果是按 ID 列出的數據幀列表。 可以將這些綁定在一起並根據最終意圖進行重塑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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