使 rollApply() 跳过 n 个步骤 - R
Making rollApply() skip n steps - R
下面是我对最小可重现示例的尝试。简而言之,我正在使用 rowr 包中的 rollApply 来计算滚动 window 上的函数,并同时使用来自两列的数据。如果可能的话,我想在每次在新的 window 上计算函数之间跳过 n 个步骤。我将尝试在下面的示例中阐明我的意思。
示例数据如下:
df1 <- tibble(
x = c(1:9),
y = c(1:9),
Date = as.Date(c("2015-08-08", "2015-08-15", "2015-08-22",
"2015-08-29","2015-09-05", "2015-09-12", "2015-09-19",
"2015-09-26", "2015-10-03"))
)
示例函数如下:
calc_ex <- function(y){
sum(y[,1] + y[,2])
}
roll_calc_ex <- function(y){
vec <- c(rep(NA, 2), rowr::rollApply(y, calc_ex, window = 3, minimum = 3))
y <- y %>%
mutate(estimate = vec)
return(y)
}
将函数 roll_calc_ex() 应用于 df1,我得到以下输出:
> roll_calc_ex(df1)
# A tibble: 9 x 4
x y Date estimate
<int> <int> <date> <int>
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 18
5 5 5 2015-09-05 24
6 6 6 2015-09-12 30
7 7 7 2015-09-19 36
8 8 8 2015-09-26 42
9 9 9 2015-10-03 48
理想情况下,我希望滚动 window 跳过 n 个步骤,比如 n=2,以产生以下输出:
# A tibble: 9 x 4
x y Date estimate
<int> <int> <date> <int>
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 NA
5 5 5 2015-09-05 NA
6 6 6 2015-09-12 30
7 7 7 2015-09-19 NA
8 8 8 2015-09-26 NA
9 9 9 2015-10-03 48
或者,不是为跳过的每一行返回 NA,而是可以填充之前计算的数字(我打算稍后使用 tidyverse 中的 fill() 来做)。
如果可以使用例如 zoo 包中的 rollapply() 来解决这个问题,那也很有趣。我只使用 rowr::rollApply() 因为我需要同时将函数应用于两列。我知道可以使用包“运行ner”中的 运行ner(),但在我更复杂的问题中,我需要 运行 并行计算。我正在使用 furrr 包进行并行化,我的代码可以很好地与 rollApply 一起使用,但不能与 运行ner() 一起使用。 运行ner 的问题在此处解释:Problem with parallelization using furrr [and runner::runner() ] in R .
感谢所有花时间阅读本文的人 post。任何帮助将不胜感激。
1) rowr 包已从 CRAN 中删除,但我们可以使用 rollapplyr
(类似于 rollapply
,但最后的 r
表示默认为右对齐)来自 zoo,它有一个 by.column=
参数来指定是逐列执行处理(TRUE)还是一次传递所有列(FALSE)和一个 by=
参数导致跳过。
library(dplyr)
library(zoo)
mutate(df1, roll =
rollapplyr(cbind(x, y), 3, calc_ex, fill = NA, by.column = FALSE, by = 2)
)
给予:
x y Date roll
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 NA
5 5 5 2015-09-05 24
6 6 6 2015-09-12 NA
7 7 7 2015-09-19 36
8 8 8 2015-09-26 NA
9 9 9 2015-10-03 48
2) 使用复数运算也可以:
f <- function(v) calc_ex(cbind(Re(v), Im(v)))
mutate(df1, roll = rollapplyr(x + y * 1i, 3, f, fill = NA, by = 2))
3) 如果我们研究 call_ex 那么它可以写成(尽管这不能概括):
mutate(df1, roll = rollapplyr(x + y, 3, sum, fill = NA, by = 2))
4) 我们也可以考虑使用动物园对象而不是数据框:
z <- read.zoo(df1, index = "Date")
merge(z, roll = rollapplyr(z, 3, calc_ex, by.column = FALSE, by = 2))
如果我们要使用滑块包
library(tidyverse)
library(slider)
df1 <- tibble(
x = c(1:9),
y = c(1:9),
Date = as.Date(c("2015-08-08", "2015-08-15", "2015-08-22",
"2015-08-29","2015-09-05", "2015-09-12", "2015-09-19",
"2015-09-26", "2015-10-03")))
df1 |>
mutate(rolling_sum = slide2_dbl(.x = x,.y = y,.f = sum,
.step = 3,.before = 2,.complete = T
))
#> # A tibble: 9 x 4
#> x y Date rolling_sum
#> <int> <int> <date> <dbl>
#> 1 1 1 2015-08-08 NA
#> 2 2 2 2015-08-15 NA
#> 3 3 3 2015-08-22 12
#> 4 4 4 2015-08-29 NA
#> 5 5 5 2015-09-05 NA
#> 6 6 6 2015-09-12 30
#> 7 7 7 2015-09-19 NA
#> 8 8 8 2015-09-26 NA
#> 9 9 9 2015-10-03 48
由 reprex package (v2.0.1)
于 2021-10-21 创建
下面是我对最小可重现示例的尝试。简而言之,我正在使用 rowr 包中的 rollApply 来计算滚动 window 上的函数,并同时使用来自两列的数据。如果可能的话,我想在每次在新的 window 上计算函数之间跳过 n 个步骤。我将尝试在下面的示例中阐明我的意思。
示例数据如下:
df1 <- tibble(
x = c(1:9),
y = c(1:9),
Date = as.Date(c("2015-08-08", "2015-08-15", "2015-08-22",
"2015-08-29","2015-09-05", "2015-09-12", "2015-09-19",
"2015-09-26", "2015-10-03"))
)
示例函数如下:
calc_ex <- function(y){
sum(y[,1] + y[,2])
}
roll_calc_ex <- function(y){
vec <- c(rep(NA, 2), rowr::rollApply(y, calc_ex, window = 3, minimum = 3))
y <- y %>%
mutate(estimate = vec)
return(y)
}
将函数 roll_calc_ex() 应用于 df1,我得到以下输出:
> roll_calc_ex(df1)
# A tibble: 9 x 4
x y Date estimate
<int> <int> <date> <int>
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 18
5 5 5 2015-09-05 24
6 6 6 2015-09-12 30
7 7 7 2015-09-19 36
8 8 8 2015-09-26 42
9 9 9 2015-10-03 48
理想情况下,我希望滚动 window 跳过 n 个步骤,比如 n=2,以产生以下输出:
# A tibble: 9 x 4
x y Date estimate
<int> <int> <date> <int>
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 NA
5 5 5 2015-09-05 NA
6 6 6 2015-09-12 30
7 7 7 2015-09-19 NA
8 8 8 2015-09-26 NA
9 9 9 2015-10-03 48
或者,不是为跳过的每一行返回 NA,而是可以填充之前计算的数字(我打算稍后使用 tidyverse 中的 fill() 来做)。
如果可以使用例如 zoo 包中的 rollapply() 来解决这个问题,那也很有趣。我只使用 rowr::rollApply() 因为我需要同时将函数应用于两列。我知道可以使用包“运行ner”中的 运行ner(),但在我更复杂的问题中,我需要 运行 并行计算。我正在使用 furrr 包进行并行化,我的代码可以很好地与 rollApply 一起使用,但不能与 运行ner() 一起使用。 运行ner 的问题在此处解释:Problem with parallelization using furrr [and runner::runner() ] in R .
感谢所有花时间阅读本文的人 post。任何帮助将不胜感激。
1) rowr 包已从 CRAN 中删除,但我们可以使用 rollapplyr
(类似于 rollapply
,但最后的 r
表示默认为右对齐)来自 zoo,它有一个 by.column=
参数来指定是逐列执行处理(TRUE)还是一次传递所有列(FALSE)和一个 by=
参数导致跳过。
library(dplyr)
library(zoo)
mutate(df1, roll =
rollapplyr(cbind(x, y), 3, calc_ex, fill = NA, by.column = FALSE, by = 2)
)
给予:
x y Date roll
1 1 1 2015-08-08 NA
2 2 2 2015-08-15 NA
3 3 3 2015-08-22 12
4 4 4 2015-08-29 NA
5 5 5 2015-09-05 24
6 6 6 2015-09-12 NA
7 7 7 2015-09-19 36
8 8 8 2015-09-26 NA
9 9 9 2015-10-03 48
2) 使用复数运算也可以:
f <- function(v) calc_ex(cbind(Re(v), Im(v)))
mutate(df1, roll = rollapplyr(x + y * 1i, 3, f, fill = NA, by = 2))
3) 如果我们研究 call_ex 那么它可以写成(尽管这不能概括):
mutate(df1, roll = rollapplyr(x + y, 3, sum, fill = NA, by = 2))
4) 我们也可以考虑使用动物园对象而不是数据框:
z <- read.zoo(df1, index = "Date")
merge(z, roll = rollapplyr(z, 3, calc_ex, by.column = FALSE, by = 2))
如果我们要使用滑块包
library(tidyverse)
library(slider)
df1 <- tibble(
x = c(1:9),
y = c(1:9),
Date = as.Date(c("2015-08-08", "2015-08-15", "2015-08-22",
"2015-08-29","2015-09-05", "2015-09-12", "2015-09-19",
"2015-09-26", "2015-10-03")))
df1 |>
mutate(rolling_sum = slide2_dbl(.x = x,.y = y,.f = sum,
.step = 3,.before = 2,.complete = T
))
#> # A tibble: 9 x 4
#> x y Date rolling_sum
#> <int> <int> <date> <dbl>
#> 1 1 1 2015-08-08 NA
#> 2 2 2 2015-08-15 NA
#> 3 3 3 2015-08-22 12
#> 4 4 4 2015-08-29 NA
#> 5 5 5 2015-09-05 NA
#> 6 6 6 2015-09-12 30
#> 7 7 7 2015-09-19 NA
#> 8 8 8 2015-09-26 NA
#> 9 9 9 2015-10-03 48
由 reprex package (v2.0.1)
于 2021-10-21 创建