dplyr 中带条件的递归函数
Recursive function with condition in dplyr
先上一个样本数据
set.seed(123)
dat <- tibble(x = sample(-10:10, size = 11,replace = T))
# A tibble: 11 x 1
x
<int>
1 -4
2 6
3 -2
4 8
5 9
6 -10
7 1
8 8
9 1
10 -1
11 10
我有一个初始值为 2 的变量 y。我想通过在给定的时间步长中将 x
添加到 y 来计算 y 的最终值,使用:
y[i] = y[i-1] + x[i]
dat %>% mutate(y = accumulate(x, ~ .x + .y, .init = 2)[-1])
# A tibble: 11 x 2
x y
<int> <dbl>
1 -4 -2
2 6 4
3 -2 2
4 8 10
5 9 19
6 -10 9
7 1 10
8 8 18
9 1 19
10 -1 18
11 10 28
但是,我要施加的条件是在给定的时间步长中,y 不能 > 10 或为负数。如果 y > 10,则为 10,如果 y < 0,则为 0。因此,实际
y(在下面的 y1 中显示)应该是:
# A tibble: 11 x 2
x y y1
<int> <dbl>
1 -4 -2 0 (-2 converted to 0)
2 6 4 6
3 -2 2 4
4 8 10 10 (12 converted to 10)
5 9 19 10 (19 converted to 10)
6 -10 9 0
7 1 10 1
8 8 18 9
9 1 19 10
10 -1 18 9
11 10 28 10 (19 converte to 10)
您只需要重新定义用于 accumulate
的函数:
library(tidyverse)
set.seed(123)
dat <- tibble(x = sample(-10:10, size = 11,replace = T))
fn <- function(x, y) pmax(pmin(x + y, 10), 0)
dat %>%
mutate(y = accumulate(x, fn, .init = 2)[-1])
dat
# A tibble: 11 × 2
x y
<int> <dbl>
1 -4 0
2 6 6
3 -2 4
4 8 10
5 9 10
6 -10 0
7 1 1
8 8 9
9 1 10
10 -1 9
11 10 10
工作原理:pmax
取两个值中的最大值,pmin
取最小值,因此您将 x+y
的总和包装到上限和下限中以限制结果在你需要的范围内。
kgolyaev 用非常相似的方法比我快了几分钟。
dat %>% mutate(y = accumulate(x, ~min(max(.x + .y, 0), 10), .init = 2)[-1])
先上一个样本数据
set.seed(123)
dat <- tibble(x = sample(-10:10, size = 11,replace = T))
# A tibble: 11 x 1
x
<int>
1 -4
2 6
3 -2
4 8
5 9
6 -10
7 1
8 8
9 1
10 -1
11 10
我有一个初始值为 2 的变量 y。我想通过在给定的时间步长中将 x
添加到 y 来计算 y 的最终值,使用:
y[i] = y[i-1] + x[i]
dat %>% mutate(y = accumulate(x, ~ .x + .y, .init = 2)[-1])
# A tibble: 11 x 2
x y
<int> <dbl>
1 -4 -2
2 6 4
3 -2 2
4 8 10
5 9 19
6 -10 9
7 1 10
8 8 18
9 1 19
10 -1 18
11 10 28
但是,我要施加的条件是在给定的时间步长中,y 不能 > 10 或为负数。如果 y > 10,则为 10,如果 y < 0,则为 0。因此,实际 y(在下面的 y1 中显示)应该是:
# A tibble: 11 x 2
x y y1
<int> <dbl>
1 -4 -2 0 (-2 converted to 0)
2 6 4 6
3 -2 2 4
4 8 10 10 (12 converted to 10)
5 9 19 10 (19 converted to 10)
6 -10 9 0
7 1 10 1
8 8 18 9
9 1 19 10
10 -1 18 9
11 10 28 10 (19 converte to 10)
您只需要重新定义用于 accumulate
的函数:
library(tidyverse)
set.seed(123)
dat <- tibble(x = sample(-10:10, size = 11,replace = T))
fn <- function(x, y) pmax(pmin(x + y, 10), 0)
dat %>%
mutate(y = accumulate(x, fn, .init = 2)[-1])
dat
# A tibble: 11 × 2
x y
<int> <dbl>
1 -4 0
2 6 6
3 -2 4
4 8 10
5 9 10
6 -10 0
7 1 1
8 8 9
9 1 10
10 -1 9
11 10 10
工作原理:pmax
取两个值中的最大值,pmin
取最小值,因此您将 x+y
的总和包装到上限和下限中以限制结果在你需要的范围内。
kgolyaev 用非常相似的方法比我快了几分钟。
dat %>% mutate(y = accumulate(x, ~min(max(.x + .y, 0), 10), .init = 2)[-1])