【问题标题】:Cumulative aggregates within tidyversetidyverse 中的累积聚合
【发布时间】:2018-05-30 08:33:43
【问题描述】:

假设我有一个由两列组成的tibble(或data.table):

a <- tibble(id = rep(c("A", "B"), each = 6), val = c(1, 0, 0, 1 ,0,1,0,0,0,1,1,1))

此外,我有一个名为myfun 的函数,它接受一个任意长度的数字向量作为输入并返回一个数字。例如,您可以将myfun 视为标准差。

现在我想为我的tibble(称为结果)创建第三列,其中包含myfun 的输出,该输出应用于 val 累积并相对于 id 分组。 例如,结果的第一个条目应包含mfun(val[1])。 第二个条目应包含myfun(val[1:2]),依此类推。 我想实现 myfun 的累积版本。

当然,在tidyverse 之外还有很多简单的解决方案,使用循环等等。 但我会对tidyversedata.table 框架内的解决方案感兴趣。

感谢任何帮助。

【问题讨论】:

    标签: r dataframe dplyr tidyverse purrr


    【解决方案1】:

    你可以这样做:

    library(tidyverse)
    
    a %>% 
      group_by(id) %>% 
      mutate(y = map_dbl(seq_along(val),~sd(val[1:.x]))) %>%
      ungroup
    
    # # A tibble: 12 x 3
    #       id   val         y
    #    <chr> <dbl>     <dbl>
    #  1     A     1        NA
    #  2     A     0 0.7071068
    #  3     A     0 0.5773503
    #  4     A     1 0.5773503
    #  5     A     0 0.5477226
    #  6     A     1 0.5477226
    #  7     B     0        NA
    #  8     B     0 0.0000000
    #  9     B     0 0.0000000
    # 10     B     1 0.5000000
    # 11     B     1 0.5477226
    # 12     B     1 0.5477226
    

    说明

    我们首先使用tidyverse 链进行分组,然后使用mutate,而不是summarize,因为我们希望保持相同的未聚合行。

    函数map_dbl 在这里用于循环最终索引的向量。 seq_along(val) 将是 1:6 对于此处的两个组。

    使用 map 系列中的函数,我们可以使用 ~ 表示法,这将假定函数的第一个参数名为 .x

    循环遍历这些索引,我们首先计算sd(val[1:1])sd(val[1])NA,然后计算sd(val[1:2]) 等等...

    map_dbl 按设计返回doubles 的向量,这些向量堆叠在y 列中。

    【讨论】:

    • 很高兴我能帮上忙 ;)
    【解决方案2】:

    可以使用动态宽度的zoo::rollapplyr (vector containing width)。可以使用1:n()seq(n()) 为每个组准备动态宽度。

    让我们使用OP 提供的数据将其应用于函数sd

    library(dplyr)
    library(zoo)
    
    a %>% group_by(id) %>%
      mutate(y = rollapplyr(val, 1:n(), sd ))
    
    #   # Groups: id [2]
    #   id      val      y
    #   <chr> <dbl>  <dbl>
    #  1 A      1.00 NA    
    #  2 A      0     0.707
    #  3 A      0     0.577
    #  4 A      1.00  0.577
    #  5 A      0     0.548
    #  6 A      1.00  0.548
    #  7 B      0    NA    
    #  8 B      0     0    
    #  9 B      0     0    
    # 10 B      1.00  0.500
    # 11 B      1.00  0.548
    # 12 B      1.00  0.548
    

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 2016-07-28
      • 1970-01-01
      • 2022-01-13
      • 2016-05-12
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多