以累积方式在数据框列表中建立一个值

Build up a value in a list of dataframes in a cumulative manner

数据框列表:

mylist <- diamonds %>% 
  mutate(somenum = rnorm(nrow(.))) %>% 
  group_by(cut, color) %>% 
  group_split %>% 
  map(~ list(dta = ., initial_val = rnorm(1)))

例如我的列表中的第一项:

mylist[1]
[[1]]
[[1]]$dta
# A tibble: 163 x 11
   carat cut   color clarity depth table price     x     y     z somenum
   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>   <dbl>
 1  0.75 Fair  D     SI2      64.6    57  2848  5.74  5.72  3.7    0.302
 2  0.71 Fair  D     VS2      56.9    65  2858  5.89  5.84  3.34   0.500
 3  0.9  Fair  D     SI2      66.9    57  2885  6.02  5.9   3.99   0.179
 4  1    Fair  D     SI2      69.3    58  2974  5.96  5.87  4.1    1.25 
 5  1.01 Fair  D     SI2      64.6    56  3003  6.31  6.24  4.05  -0.731
 6  0.73 Fair  D     VS1      66      54  3047  5.56  5.66  3.7    0.758
 7  0.71 Fair  D     VS2      64.7    58  3077  5.61  5.58  3.62  -1.43 
 8  0.91 Fair  D     SI2      62.5    66  3079  6.08  6.01  3.78   0.820
 9  0.9  Fair  D     SI2      65.9    59  3205  6     5.95  3.94  -1.81 
10  0.9  Fair  D     SI2      66      58  3205  6     5.97  3.95  -0.179
# … with 153 more rows

[[1]]$initial_val
[1] 1.788348

列表项包含一个数据框和一个数字'initial_val'。

对于列表中的每个数据框,我想在其上变异一个新字段 'cumsum_someval',该字段以列表项的 initial_val 开头,然后通过添加 'builds it up' initial_val 的滞后 cumsum 与 somenum 的行条目。例如。第一行,cumsum_someval 的值将只是 initial_val 1.788348。但是第二行cumsum_someval应该是1.788348 + 0.302 = 2.090348。然后,第 3 行将是 2.090348 + 0.500 = 2.590348。等等。

也许类似 purrr::map 的自定义函数...?

myfun <- function(dta, initial_val) {
  cum_val = initial_val + dta$somenum[<rownumber here>]
}

接受建议。

对于 mylist 中的每个数据框,我如何构建这个以 initial_val 开头的新变异字段,然后对每个 somenum 实例的滞后求和?

我们用 map 遍历 list,提取 'dta' 数据集,通过获取 laglag 创建新的 'cum_val' 22=],将 default 指定为 'initial_val',执行 cumsum,将输出分配回 'dta' 和 return 整个 list 元素即 .x

library(purrr)
library(dplyr)
map(mylist, ~ {
       .x$dta <- .x$dta %>%
         mutate(cum_val = cumsum(lag(somenum, default = .x$initial_val)))
     .x

      })

虽然这不像 Arun 的解决方案那么优雅,但我会把它献给他,也献给 Doug,他时不时地向我们提出非常好的挑战:

library(purrr)

mylist %>%
  map_dbl("initial_val") %>%
  map2(mylist, function(a, b) {
    b %>% imap(~ if(.y == "dta") {
      .x %>% mutate(cumsum_someval = accumulate(c(a, .x$somenum[-nrow(.x)]), `+`))
    } else {
      .x
    })
  }) %>% `[`(1)

[[1]]
[[1]]$dta
# A tibble: 163 x 12
   carat cut   color clarity depth table price     x     y     z somenum cumsum_someval
   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>   <dbl>          <dbl>
 1  0.75 Fair  D     SI2      64.6    57  2848  5.74  5.72  3.7   0.0684         0.0391
 2  0.71 Fair  D     VS2      56.9    65  2858  5.89  5.84  3.34  0.436          0.108 
 3  0.9  Fair  D     SI2      66.9    57  2885  6.02  5.9   3.99 -0.0591         0.543 
 4  1    Fair  D     SI2      69.3    58  2974  5.96  5.87  4.1   1.08           0.484 
 5  1.01 Fair  D     SI2      64.6    56  3003  6.31  6.24  4.05 -0.478          1.57  
 6  0.73 Fair  D     VS1      66      54  3047  5.56  5.66  3.7  -0.600          1.09  
 7  0.71 Fair  D     VS2      64.7    58  3077  5.61  5.58  3.62 -0.825          0.487 
 8  0.91 Fair  D     SI2      62.5    66  3079  6.08  6.01  3.78 -1.09          -0.338 
 9  0.9  Fair  D     SI2      65.9    59  3205  6     5.95  3.94 -0.672         -1.42  
10  0.9  Fair  D     SI2      66      58  3205  6     5.97  3.95 -0.273         -2.10  
# ... with 153 more rows

[[1]]$initial_val
[1] 0.03913573