按R中其他列分组的滚动3年总和

polhcujo  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(98)

我的数据框只有年度数据,我想创建一个3年期间的总和,按列名NOC、NAICS、Region分组。
| 区域性|NAICS|日期|年份|数值| Value |
| --|--|--|--|--| ------------ |
| 东|AA|二〇一〇年|2010年12月31日|三个| 3 |
| 东|AA|二〇一一年|2011年12月31日|四| 4 |
| 东|AA|二〇一二年|2012年12月31日|0| 0 |
| 西|BB|二〇一〇年|2010年12月31日|一百| 100 |
| 西|BB|二〇一一年|2011年12月31日|两百| 200 |
| 西|BB|二〇一二年|2012年12月31日|两百| 200 |
| 北|CC|二〇一〇年|2010年12月31日|二十三| -23 |
| 北|CC|二〇一一年|2011年12月31日|三个| 3 |
| 北|CC|二〇一一年|2011年12月31日|二十| 20 |
新的df应该看起来像
| 区域性|NAICS|日期|年份|数值|总和| Sum |
| --|--|--|--|--|--| ------------ |
| 东|AA|二〇一〇年|2010年12月31日|三个|七| 7 |
| 东|AA|二〇一一年|2011年12月31日|四|不适用| NA |
| 东|AA|二〇一二年|2012年12月31日|0|不适用| NA |
| 西|BB|二〇一〇年|2010年12月31日|一百|五百| 500 |
| 西|BB|二〇一一年|2011年12月31日|两百|不适用| NA |
| 西|BB|二〇一二年|2012年12月31日|两百|不适用| NA |
| 北|CC|二〇一一年|2010年12月31日|二十三|0| 0 |
| 北|CC|二〇一一年|2011年12月31日|三个|不适用| NA |
| 北|CC|二〇一一年|2011年12月31日|二十|不适用| NA |
我试过这个,但不能让它工作。

df %>%
  group_by(NOC, Region,  NAICS, Date) %>%
  mutate(max = rollapplyr(Value, 1:n() - findInterval(date - 5, Date), sum)) %>%
  slice_max(max) %>%
  ungroup %>%

字符串

a2mppw5e

a2mppw5e1#

rollapply函数可以在固定窗口大小下使用,如果您确定时间戳是均匀分布的。

library(dplyr)
library(zoo)

df |>
    group_by(NOC, Region, NAICS) |>
    mutate(Sum = rollapply(Value, 3, sum, fill = NA, align = "left"))

字符串
如果时间戳之间的距离不相等,则需要使用带有宽度向量的rollapply。这个向量可以按照下面的代码片段中所描述的方法计算,其中findIntervall查找区间的边界。

gf <- df |> 
          group_by(Region)|>
          mutate(width = findInterval(Date + 3 , Date) - seq_along(Date) + 1,
          results = rollapply(Value, width, sum, fill=NA, align="left"))


但是,您不会获得NA值。要做到这一点,你必须想出一些规则来确定一个三年周期的开始。

ldfqzlk8

ldfqzlk82#

单程:

library(tidyverse)

df %>%
  group_by(NOC, Region, NAICS) %>%
  mutate(Sum = rollsum(Value, 3, fill = NA, align = "left"))

字符串
或者

df %>%
  group_by(NOC, Region, NAICS) %>%
  mutate(Sum = Value + lead(Value) + lead(lead(Value)))


或者使用rollapply

df %>%
  group_by(NOC, Region, NAICS) %>%
  mutate(Sum = rollapply(Value, 3, sum, fill = NA, align = "left"))


这些都是假设你有完整的数据(即,数据中没有间隙,并且都是均匀间隔的(即,它不去2011年,2012年,2014年,2014年),它看起来像你的数据不这样做。在这种情况下,这样的话会更合适:

df %>%
  mutate(Date = mdy(Year),
        Year = year(Date)) %>%
  group_by(NOC, Region, NAICS) %>%
  mutate(
        Sum = map_dbl(Date, ~sum(Value[between(Date, .x, .x + years(3))])))


然而,这需要接下来三年的值的总和,这不会像您的示例中那样创建一堆NA,因为它只是寻找它可以找到的NA(您可以将其视为积极或消极,这取决于您的观点)。
或者,如果要将数据拆分为离散的3年组:

df %>%
  mutate(Date = mdy(Year),
        Year = year(Date)) %>%
  group_by(NOC, Region, NAICS) %>%
  # round to the yearest three year chunk
  mutate(Group = round(as.numeric(Date - min(Date))/1462)+1) %>%
  group_by(NOC, Region, NAICS, Group) %>%
  mutate(Value = ifelse(Year == first(Year), sum(Value), NA))

5tmbdcev

5tmbdcev3#

请尝试下面的代码

df %>% mutate(rle=row_number(),
             sum=ifelse(rle==1,sum(Value),NA), .by=c(NOC,Region,NAICS)) %>% select(-rle)
# A tibble: 9 × 7
    NOC Region NAICS  Date Year       Value   sum
  <dbl> <chr>  <chr> <dbl> <chr>      <dbl> <dbl>
1     0 East   AA     2010 12/31/2010     3     7
2     0 East   AA     2011 12/31/2011     4    NA
3     0 East   AA     2012 12/31/2012     0    NA
4     0 West   BB     2010 12/31/2010   100   500
5     0 West   BB     2011 12/31/2011   200    NA
6     0 West   BB     2012 12/31/2012   200    NA
7     0 North  CC     2010 12/31/2010   -23     0
8     0 North  CC     2011 12/31/2011     3    NA
9     0 North  CC     2011 12/31/2011    20    NA

相关问题