R语言 将2个变量的每周数据平均为每月数据

w41d8nur  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(158)

我有两列,每一周的开始和结束日期。我需要按月通过特定月份的平均周数来聚合其他列(我有3年的数据集),并创建另一列,将包含整个月的重量(因此它将在5 - 6周内是相同的值,取决于特定的ID在特定的月份有多少周(我在数据集中有数千个ID)。棘手的是,有些周是重叠的,因此,有时一行会被纳入两个月的计算中,例如,当我们有start_date = 2020 - 07 - 27和end_date = 2020 - 08 - 09时(必须同时计入7月和8月)。这是我的数据:
| 识别号|重量|开始日期|结束日期|
| - ------|- ------|- ------|- ------|
| 六十|一、二|2019年12月30日|2020年1月5日|
| 六十|一、四|2020年1月6日|2020年1月12日|
| 六十|一、三|2020年1月13日|2020年1月19日|
| 六十|1.0秒|2020年1月20日|2020年1月26日|
| 六十|三、八|2020年1月27日|2020年2月2日|
| 六十一|一、七|2019年12月30日|2020年1月5日|
| 六十一|十二、九|2020年1月6日|2020年1月12日|
我想获得:
| 识别号|重量|开始日期|结束日期|月_体重|月份|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 六十|一、二|二〇二〇年十二月三十日|2020年1月5日|一、七十四|二○二○年一月|
| 六十|一、四|2020年1月6日|2020年1月12日|一、七十四|二○二○年一月|
| 六十|一、三|2020年1月13日|2020年1月19日|一、七十四|二○二○年一月|
| 六十|1.0秒|2020年1月20日|2020年1月26日|一、七十四|二○二○年一月|
| 六十|三、八|2020年1月27日|2020年2月2日|一、七十四|二○二○年一月|
| 六十一|一、七|二〇二〇年十二月三十日|2020年1月5日|七、三|二○二○年一月|
| 六十一|十二、九|2020年1月6日|2020年1月12日|七、三|二○二○年一月|
首先,我想做一个循环,检测两列中的每个月,如果月份出现,它将从其他列中取平均值,但后来我发现堆栈溢出(How to convert weekly data into monthly data?)有类似的问题,并决定使用zoo。
我试着从上面的职位实施解决方案:

library(zoo)
z.st <- read.zoo(long_weights[c("start_date", "weight")])
z.en <- read.zoo(long_weights[c("end_date", "weight")])
z <- c(z.st, z.en)

g <- zoo(, seq(start(z), end(z), "day"))
m <- na.locf(merge(z, g))
aggregate(m, as.yearmon, mean)

但是在这一行之后:

z <- c(z.st, z.en)

我得到一个错误:绑定. zoo(...)时出错:指标重叠
我也试过了,但这没有考虑到重叠的几周:

df <- df %>% group_by(HHKEY, month = floor_date((as.Date(end_date)- as.Date(start_date))/2 + as.Date(start_date), "month")) %>% mutate(monthly_weight = mean(weight), .after = end_date, month = format(month, "%Y.%m")) %>% ungroup()
x8diyxa7

x8diyxa71#

一种可能的解决方案是,当a start_date a与分组变量 month 的结束日期不同时(在月末),获取每个月的 start_date。扩展数据以包括 ID 内的年份变化。

library(dplyr)

df %>% 
  group_by(ID) %>% 
  mutate(start_date = as.Date(start_date), end_date = as.Date(end_date), 
         month = lead(format(start_date, "%m.%Y")), 
         month = if_else(is.na(month), 
           format(start_date, "%m.%Y"), format(end_date, "%m.%Y"))) %>% 
  group_by(ID, month) %>% 
  mutate(monthly_weight = mean(weight), .before=month) %>% 
  ungroup()
# A tibble: 14 × 6
      ID weight start_date end_date   monthly_weight month  
   <dbl>  <dbl> <date>     <date>              <dbl> <chr>  
 1    60    1.2 2019-12-30 2020-01-05           1.74 01.2020
 2    60    1.4 2020-01-06 2020-01-12           1.74 01.2020
 3    60    1.3 2020-01-13 2020-01-19           1.74 01.2020
 4    60    1   2020-01-20 2020-01-26           1.74 01.2020
 5    60    3.8 2020-01-27 2020-02-02           1.74 01.2020
 6    61    1.7 2019-12-30 2020-01-05           7.3  01.2020
 7    61   12.9 2020-01-06 2020-01-12           7.3  01.2020
 8    61    1.2 2020-12-29 2021-01-04           1.74 01.2021
 9    61    1.4 2021-01-05 2021-01-11           1.74 01.2021
10    61    1.3 2021-01-12 2021-01-18           1.74 01.2021
11    61    1   2021-01-19 2021-01-25           1.74 01.2021
12    61    3.8 2021-01-26 2021-02-01           1.74 01.2021
13    63    1.7 2020-12-29 2021-01-04           7.3  01.2021
14    63   12.9 2021-01-05 2021-01-11           7.3  01.2021
扩展数据
df <- structure(list(ID = c(60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 
61, 61, 63, 63), weight = c(1.2, 1.4, 1.3, 1, 3.8, 1.7, 12.9, 
1.2, 1.4, 1.3, 1, 3.8, 1.7, 12.9), start_date = structure(c(18260, 
18267, 18274, 18281, 18288, 18260, 18267, 18625, 18632, 18639, 
18646, 18653, 18625, 18632), class = "Date"), end_date = structure(c(18266, 
18273, 18280, 18287, 18294, 18266, 18273, 18631, 18638, 18645, 
18652, 18659, 18631, 18638), class = "Date")), row.names = c(NA, 
-14L), class = c("tbl_df", "tbl", "data.frame"))

相关问题