dplyr :: filter () на основе dplyr :: 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))

person Joe    schedule 25.04.2018    source источник
comment
@joran, подобная манипуляция аргументом по умолчанию - хорошее решение, и его можно обновить до filter (hp ›lag (hp, default = hp [1] - 1)) в случаях, когда эквивалентности недостаточно.   -  person Joe    schedule 25.04.2018


Ответы (2)


Наличие filter(hp <= lag(hp)) исключает строки, где lag(hp) равно NA. Вместо этого вы можете отфильтровать либо это неравенство , либо для 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 
person camille    schedule 25.04.2018

Поскольку OP намеревается использовать <= (меньше или равно) с предыдущим значением, поэтому использования lag с default = +Inf будет достаточно.

Кроме того, нет необходимости иметь отдельный вызов arrange в цепочке dplyr, поскольку lag предоставляет возможность выбора 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
person MKR    schedule 25.04.2018