【问题标题】:Build up a value in a list of dataframes in a cumulative manner以累积方式在数据框列表中建立一个值
【发布时间】:2021-07-08 17:40:11
【问题描述】:

数据框列表:

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

例如mylist 中的第一项:

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 开头,然后通过将 initial_val 的滞后累积和与行相加来“构建它” somenum的条目。例如。第一行,cumsum_someval 的值就是 initial_val 1.788348。但是cumsum_someval的第二行应该是1.788348 + 0.302 = 2.090348。然后,第三行将是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 的每个实例的滞后?

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    我们用map循环list,提取'dta'数据集,创建新的'cum_val',取'somenum'的lag,指定default为'initial_val',执行cumsum,将输出分配回'dta'并返回整个list元素,即.x

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

    【讨论】:

    • 虽然,它并不能解决我的现实问题。由于cumsum() 函数的存在,它消除了我在真实数据上的复杂性,我不需要cumsum,但我确实需要采用initial_val,应用自定义函数,获取该自定义的输出func 为每一行,也许重新分配到 initial_val 并重复。 IE。输出需要是使用自定义函数的下一次迭代的输入。这个答案在回答这个问题时“太好了”,特别是我是如何问的。也许我应该发布一个有一些限制的新的:/
    • @DougFir 如果是这种情况,您可以使用accumulateaccumulate(somenum, .f = yourfun, .init = .x$initial_val) 进行此操作
    • 换种说法,有没有一种方法可以让我更加手动,在其中更新突变中每一行的“initial_val”对应值的列表?回复acumulate()。是的,我以前用过它,但我个人觉得它很难阅读。如果可行,您会更喜欢这种更手动的方法,您认为吗?
    • @DougFir 你能检查我编辑的评论吗?是你要找的代码吗
    • 善用我学到的一切:)
    【解决方案2】:

    虽然这不如 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-05
      • 2013-10-03
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      相关资源
      最近更新 更多