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

dplyr::filter()基于dplyr::lag()而不丢失第一个值

  •  4
  • Joe  · 技术社区  · 6 年前

    基于lag()函数过滤数据集时,会丢失每组中的第一行(因为这些行没有lag值)。如何避免这种情况,以便在第一行没有任何滞后值的情况下保持它们?

    ds <- 
      structure(list(mpg = c(21, 21, 21.4, 18.7, 14.3, 16.4), cyl = c(6, 
      6, 6, 8, 8, 8), hp = c(110, 110, 110, 175, 245, 180)), class = c("tbl_df", 
      "tbl", "data.frame"), row.names = c(NA, -6L), .Names = c("mpg", 
      "cyl", "hp"))
    
    # example of filter based on lag that drops first rows
    ds %>% 
      group_by(cyl) %>% 
      arrange(-mpg) %>% 
      filter(hp <= lag(hp))
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   camille    6 年前

    拥有 filter(hp <= lag(hp)) 排除其中的行 lag(hp) NA 。您可以改为筛选 任何一个 这种不平等 对于 滞后(hp) ,每个组的顶行也是如此。

    我包括 prev = lag(hp) 为LAG创建一个独立变量,仅为清楚起见(&调试。

    library(tidyverse)
    
    ds %>%
        group_by(cyl) %>%
        arrange(-mpg) %>%
        mutate(prev = lag(hp)) %>%
        filter(hp <= prev | is.na(prev))
    

    这将产生:

    # A tibble: 4 x 4
    # Groups:   cyl [2]
        mpg   cyl    hp  prev
      <dbl> <dbl> <dbl> <dbl>
    1  21.4    6.  110.   NA 
    2  21.0    6.  110.  110.
    3  21.0    6.  110.  110.
    4  18.7    8.  175.   NA 
    
        2
  •  3
  •   MKR    6 年前

    自从 OP 打算使用 <= (小于或等于)之前的值,因此使用 lag 具有 default = +Inf 就足够了。

    此外,无需单独 arrange 请来 dplyr 链组件 缓慢移动 提供选择选项 order_by

    因此,解决方案可以写成:

    ds %>% 
      group_by(cyl) %>% 
      filter(hp <= lag(hp, default = +Inf, order_by = -mpg))
    
    #Below result is in origianl order of the data.frame though lag was calculated 
    #in ordered value of mpg
    # # A tibble: 4 x 3
    # # Groups: cyl [2]
    #     mpg   cyl    hp
    #    <dbl> <dbl> <dbl>
    # 1  21.0  6.00   110
    # 2  21.0  6.00   110
    # 3  21.4  6.00   110
    # 4  18.7  8.00   175
    
    推荐文章