是否存在在 Dataframe 的每一行上重新定义自身的滞后函数

g6ll5ycj  于 2023-04-27  发布在  其他
关注(0)|答案(2)|浏览(126)

在我的dataframe中,我想根据另一个动态变化的列的先前值来定义一个列。我知道tidyverse包有滞后函数,可以返回指定列的前一行的值。但是滞后函数在动态变化期间不计算指定列的变化。
下面的例子只是为了更好的理解而对问题进行了过度简化。它重现了一个循环迭代。

library(tidyverse)

H = 10
initial_a = 10
initial_b = 0

df = tibble(period = 0:H) %>%
  mutate(
    a = initial_a,
    
    b = ifelse(is.na(lag(a)), initial_b, lag(a)),
    
    a = period * initial_a
  )

view(df)

我想得到以下结果:

period     a     b
    <int> <dbl> <dbl>
 1      0     0     0
 2      1    10     0
 3      2    20    10
 4      3    30    20
 5      4    40    30
 6      5    50    40
 7      6    60    50
 8      7    70    60
 9      8    80    70
10      9    90    80
11     10   100    90

但我得到的只有这个:

period     a     b
    <int> <dbl> <dbl>
 1      0     0     0
 2      1    10    10
 3      2    20    10
 4      3    30    10
 5      4    40    10
 6      5    50    10
 7      6    60    10
 8      7    70    10
 9      8    80    10
10      9    90    10
11     10   100    10

我知道问题出在哪里:滞后函数不是在每一行都更新。它是用'a'列的初始值计算的。
所以我的问题是是否有一个函数允许在每一步更新列'a'的值并取前一行的值。

brjng4g3

brjng4g31#

不需要循环任何东西,定义a,然后使用lag(col, default = val)创建b

library(dplyr)

initial_a = 10
initial_b = 0
H = 10

tibble(period = 0:H) %>% 
  mutate(a = period * initial_a, 
         b = lag(a, default = initial_b))
#> # A tibble: 11 x 3
#>    period     a     b
#>     <int> <dbl> <dbl>
#>  1      0     0     0
#>  2      1    10     0
#>  3      2    20    10
#>  4      3    30    20
#>  5      4    40    30
#>  6      5    50    40
#>  7      6    60    50
#>  8      7    70    60
#>  9      8    80    70
#> 10      9    90    80
#> 11     10   100    90
9udxz4iz

9udxz4iz2#

所示的例子是一个简单的算术级数,它不需要迭代,但假设真实的问题更复杂,那么Reduce给出了一种在计算后使用先前值的方法。Reduce将传递在上一次迭代中计算的值作为x,并在y中传递period的当前值(在这个问题中不使用)。

library(dplyr, exclude = c("filter", "lag"))

initial_a = 10
initial_b = 0
data.frame(period = 0:10) %>%
  mutate(a = Reduce(function(x, y) x + initial_a, period,  acc = TRUE),
         b = dplyr::lag(a, default = initial_b))

给出:

period   a  b
1       0   0  0
2       1  10  0
3       2  20 10
4       3  30 20
5       4  40 30
6       5  50 40
7       6  60 50
8       7  70 60
9       8  80 70
10      9  90 80
11     10 100 90

相关问题