R中双索引的滚动总和
Rolling sum with double indexing in R
我想计算 R 中两个索引列的滚动总和或滚动计数。以下数据 table 有一个显示销售量的列和两个日期列。我想创建第 4 列,它给出 Column index2 中的日期数小于 Column index1 中的日期,我还希望第 5 列给出与第四列相关的销售额总和列。
sales_vec <- c(2, 4, 3, 5)
index1_vec <- as.Date("2019-08-29") + c(0, 2, 5, 6)
index2_vec <- as.Date("2019-08-29") + c(-5, 2, 1, -3)
company <- tibble(
sales = sales_vec,
index1 = index1_vec ,
index2 = index2_vec
)
> print(company)
# A tibble: 4 x 3
sales index1 index2
<dbl> <date> <date>
1 2 2019-08-29 2019-08-24
2 4 2019-08-31 2019-08-31
3 3 2019-09-03 2019-08-30
4 5 2019-09-04 2019-08-26
我的结果应该是这样的:
# A tibble: 4 x 5
sales index1 index2 rollingCount rollingSum
<dbl> <date> <date> <dbl> <dbl>
1 2 2019-08-29 2019-08-24 2 7
2 4 2019-08-31 2019-08-31 3 10
3 3 2019-09-03 2019-08-30 4 14
4 5 2019-09-04 2019-08-26 4 14
rollingCount的第一行是2,因为Column index2中有两个日期小于index1的第一行,与这两行相关联的销售额之和为2 + 5 = 7,显示在 rollingSum 的第一行。 rollingCount 的第二行是 3,因为 Column index2 中有三个日期小于 index1 的第二行,与这三行相关的销售额总和为 2 + 5 + 3 = 10,显示在第二行滚动总和行。等等。
我熟悉用于滚动计算的“幻灯片”命令系列,但我很难完成这项任务,因为它有两个索引列。
在base R
中,我们可以使用sapply
遍历'index1'列,用index2
列创建一个逻辑向量,用它来得到[=逻辑向量的 15=] 和 'sales'
子集的 sum
cbind(company, t(sapply(company$index1, function(x) {
i1 <- company$index2 < x
c(rollingCount = sum(i1), rollingSum = sum(company$sales[i1])) })))
# sales index1 index2 rollingCount rollingSum
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-30 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
或者另一个选项是 tidyverse
library(dplyr)
library(purrr)
map_dfr(company$index1, ~ {
i1 <- company$index2 < .x
tibble(rollingCount = sum(i1), rollingSum = sum(company$sales[i1]))}) %>%
bind_cols(company, .)
# A tibble: 4 x 5
# sales index1 index2 rollingCount rollingSum
# <dbl> <date> <date> <int> <dbl>
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-30 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
这里有几种方法:
使用rowwise
:
library(dplyr)
library(purrr)
company %>%
rowwise() %>%
mutate(rollingCount = sum(index1 > .$index2),
rollingSum = sum(.$sales[index1 > .$index2]))
# sales index1 index2 rollingCount rollingSum
# <dbl> <date> <date> <int> <dbl>
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-31 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
并使用 purrr
中的 map_dbl
:
company %>%
mutate(rollingCount = map_dbl(index1, ~{
vec <- .x > index2
sum(vec)
}),
rollingSum = map_dbl(index1, ~sum(sales[.x > index2])))
我想计算 R 中两个索引列的滚动总和或滚动计数。以下数据 table 有一个显示销售量的列和两个日期列。我想创建第 4 列,它给出 Column index2 中的日期数小于 Column index1 中的日期,我还希望第 5 列给出与第四列相关的销售额总和列。
sales_vec <- c(2, 4, 3, 5)
index1_vec <- as.Date("2019-08-29") + c(0, 2, 5, 6)
index2_vec <- as.Date("2019-08-29") + c(-5, 2, 1, -3)
company <- tibble(
sales = sales_vec,
index1 = index1_vec ,
index2 = index2_vec
)
> print(company)
# A tibble: 4 x 3
sales index1 index2
<dbl> <date> <date>
1 2 2019-08-29 2019-08-24
2 4 2019-08-31 2019-08-31
3 3 2019-09-03 2019-08-30
4 5 2019-09-04 2019-08-26
我的结果应该是这样的:
# A tibble: 4 x 5
sales index1 index2 rollingCount rollingSum
<dbl> <date> <date> <dbl> <dbl>
1 2 2019-08-29 2019-08-24 2 7
2 4 2019-08-31 2019-08-31 3 10
3 3 2019-09-03 2019-08-30 4 14
4 5 2019-09-04 2019-08-26 4 14
rollingCount的第一行是2,因为Column index2中有两个日期小于index1的第一行,与这两行相关联的销售额之和为2 + 5 = 7,显示在 rollingSum 的第一行。 rollingCount 的第二行是 3,因为 Column index2 中有三个日期小于 index1 的第二行,与这三行相关的销售额总和为 2 + 5 + 3 = 10,显示在第二行滚动总和行。等等。
我熟悉用于滚动计算的“幻灯片”命令系列,但我很难完成这项任务,因为它有两个索引列。
在base R
中,我们可以使用sapply
遍历'index1'列,用index2
列创建一个逻辑向量,用它来得到[=逻辑向量的 15=] 和 'sales'
sum
cbind(company, t(sapply(company$index1, function(x) {
i1 <- company$index2 < x
c(rollingCount = sum(i1), rollingSum = sum(company$sales[i1])) })))
# sales index1 index2 rollingCount rollingSum
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-30 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
或者另一个选项是 tidyverse
library(dplyr)
library(purrr)
map_dfr(company$index1, ~ {
i1 <- company$index2 < .x
tibble(rollingCount = sum(i1), rollingSum = sum(company$sales[i1]))}) %>%
bind_cols(company, .)
# A tibble: 4 x 5
# sales index1 index2 rollingCount rollingSum
# <dbl> <date> <date> <int> <dbl>
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-30 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
这里有几种方法:
使用rowwise
:
library(dplyr)
library(purrr)
company %>%
rowwise() %>%
mutate(rollingCount = sum(index1 > .$index2),
rollingSum = sum(.$sales[index1 > .$index2]))
# sales index1 index2 rollingCount rollingSum
# <dbl> <date> <date> <int> <dbl>
#1 2 2019-08-29 2019-08-24 2 7
#2 4 2019-08-31 2019-08-31 3 10
#3 3 2019-09-03 2019-08-30 4 14
#4 5 2019-09-04 2019-08-26 4 14
并使用 purrr
中的 map_dbl
:
company %>%
mutate(rollingCount = map_dbl(index1, ~{
vec <- .x > index2
sum(vec)
}),
rollingSum = map_dbl(index1, ~sum(sales[.x > index2])))