【问题标题】:dplyr::filter() based on dplyr::lag() without losing first valuesdplyr::filter() 基于 dplyr::lag() 而不会丢失第一个值
【发布时间】:2018-04-25 18:43:04
【问题描述】:

当我根据 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))

【问题讨论】:

  • lag(hp,default = hp[1])?
  • @joran,以这种方式操作默认参数是一个很好的解决方案,在某些情况下可以更新为“filter(hp > lag(hp, default = hp[1] - 1))”等效性不足。

标签: r dplyr lag lead


【解决方案1】:

拥有filter(hp &lt;= lag(hp)) 不包括lag(hp)NA 的行。您可以改为过滤 either 不等式 lag(hp),就像每个组的顶部行的情况一样。

我添加了prev = lag(hp) 来为滞后创建一个独立变量,只是为了清晰和调试。

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】:

    由于OP 打算将&lt;=(小于或等于)与先前的值一起使用,因此将lagdefault = +Inf 一起使用就足够了。

    此外,由于lag 提供了选择order_by 的选项,因此无需在dplyr 链中单独调用arrange

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

    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
    

    【讨论】:

      猜你喜欢
      • 2021-07-27
      • 1970-01-01
      • 2020-12-25
      • 2023-03-30
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多