代码之家  ›  专栏  ›  技术社区  ›  Cettt

tidyverse内的累积集料

  •  1
  • Cettt  · 技术社区  · 6 年前

    说我有一个 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 作为标准差。

    现在我想为我的 蒂伯尔 (称为结果)包含 MyFun 应用于累积的VAL,并根据ID分组。 例如,结果的第一个条目应该包含 mfun(val[1]) . 第二个条目应该包含 myfun(val[1:2]) 等等。 我想用一个累积版本的myfun。

    当然有很多简单的解决方案 tidyverse 使用循环和其他方法。 但我有兴趣在 潮人 或者在 数据表 框架工程。

    感谢您的帮助。

    2 回复  |  直到 5 年前
        1
  •  6
  •   moodymudskipper    6 年前

    你可以这样做:

    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 对于这两个组。

    使用来自地图族的函数,我们可以使用 ~ 表示法,假定函数的第一个参数命名为 .x .

    我们先计算这些指数 sd(val[1:1]) 哪个是 sd(val[1]) 哪个是 NA 然后 sd(val[1:2]) 等...

    地图 按设计返回向量 doubles ,而这些都堆放在 y 列。

        2
  •  2
  •   MKR    6 年前

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

    让我们把它应用于函数 sd 使用由提供的数据 OP :

    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