#r #lubridate #dplyr
Вопрос:
У меня есть df, в котором есть две колонки, time
и val
. df упорядочен по времени. Я хочу отфильтровать все строки от максимального значения, в данном случае это так 1.29
. Я привел пример ниже:
library(tidyverse)
library(lubridate)
# This is the entire df
df1 <- tibble::tribble(
~date, ~val,
"2021-09-16 11:02:45", 1.21,
"2021-09-16 11:02:45", 1.21,
"2021-09-16 11:02:45", 1.21,
"2021-09-16 11:02:45", 1.22,
"2021-09-16 11:02:45", 1.22,
"2021-09-16 11:02:45", 1.22,
"2021-09-16 11:02:37", 1.22,
"2021-09-16 10:59:29", 1.29,
"2021-09-16 10:59:14", 1.29,
"2021-09-16 10:59:14", 1.28,
"2021-09-16 10:59:14", 1.28,
"2021-09-16 10:58:17", 1.28,
"2021-09-16 10:58:17", 1.28,
"2021-09-16 10:58:05", 1.26,
"2021-09-16 10:58:05", 1.26,
"2021-09-16 10:58:05", 1.23,
"2021-09-16 10:57:16", 1.23
) %>%
mutate(date = ymd_hms(date))
# This is the outcome I am looking for
tibble::tribble(
~date, ~val,
"2021-09-16 10:59:29", 1.29,
"2021-09-16 10:59:14", 1.29,
"2021-09-16 10:59:14", 1.28,
"2021-09-16 10:59:14", 1.28,
"2021-09-16 10:58:17", 1.28,
"2021-09-16 10:58:17", 1.28,
"2021-09-16 10:58:05", 1.26,
"2021-09-16 10:58:05", 1.26,
"2021-09-16 10:58:05", 1.23,
"2021-09-16 10:57:16", 1.23
) %>%
mutate(date = ymd_hms(date))
Как это сделать эффективно, есть какие-нибудь идеи?
Ответ №1:
Если я правильно понял, это может решить вашу проблему
library(dplyr)
df1 %>%
filter(date <= first(date[val == max(val)]))
# A tibble: 10 x 2
date val
<dttm> <dbl>
1 2021-09-16 10:59:29 1.29
2 2021-09-16 10:59:14 1.29
3 2021-09-16 10:59:14 1.28
4 2021-09-16 10:59:14 1.28
5 2021-09-16 10:58:17 1.28
6 2021-09-16 10:58:17 1.28
7 2021-09-16 10:58:05 1.26
8 2021-09-16 10:58:05 1.26
9 2021-09-16 10:58:05 1.23
10 2021-09-16 10:57:16 1.23
Комментарии:
1. вот и все! Из какой библиотеки вы
first
пришли?2. @головоногий моллюск
dplyr
Ответ №2:
Вот несколько других dplyr
вариантов использования match
.
- С помощью
slice
—
library(dplyr)
df1 %>% slice(match(max(val), val):n())
# date val
# <dttm> <dbl>
# 1 2021-09-16 10:59:29 1.29
# 2 2021-09-16 10:59:14 1.29
# 3 2021-09-16 10:59:14 1.28
# 4 2021-09-16 10:59:14 1.28
# 5 2021-09-16 10:58:17 1.28
# 6 2021-09-16 10:58:17 1.28
# 7 2021-09-16 10:58:05 1.26
# 8 2021-09-16 10:58:05 1.26
# 9 2021-09-16 10:58:05 1.23
#10 2021-09-16 10:57:16 1.23
- С помощью
filter
df1 %>% filter(row_number() >= match(max(val), val))
Вы также можете использовать базу R, чтобы сделать то же самое.
df1[match(max(df1$val), df1$val):nrow(df1), ]
Ответ №3:
Мы можем использовать
library(dplyr)
df1 %>%
filter(row_number() >=which.max(val))
-выход
# A tibble: 10 x 2
date val
<dttm> <dbl>
1 2021-09-16 10:59:29 1.29
2 2021-09-16 10:59:14 1.29
3 2021-09-16 10:59:14 1.28
4 2021-09-16 10:59:14 1.28
5 2021-09-16 10:58:17 1.28
6 2021-09-16 10:58:17 1.28
7 2021-09-16 10:58:05 1.26
8 2021-09-16 10:58:05 1.26
9 2021-09-16 10:58:05 1.23
10 2021-09-16 10:57:16 1.23
Ответ №4:
df1 %>%
filter(cumsum(val == max(val)) >= 1)
Здесь мы сохраняем строки, для которых совокупное время, в течение которого мы достигли максимального значения, составляет по крайней мере одну.
Я предполагаю, что здесь данные уже отсортированы по дате.