[英]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
中每個date
的value
,但下面的代碼似乎沒有這樣做。
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.