#r #dplyr
Вопрос:
Фрейм данных:
mydf <- data.frame(
date = seq(as.Date('2021-01-01'), as.Date('2021-01-20'), by = 'days'),
blah = rnorm(20, 0),
y = LETTERS[1:20]
)
Я хочу отфильтровать дату так, чтобы она доходила до максимального значения бла, превышающего 0.
Пытался:
mydf %>% filter(date <= (. %>% filter(blah > 0) %>% pull(date) %>% max))
Что дало ошибку:
Error: Problem with `filter()` input `..1`.
x comparison (4) is possible only for atomic and list types
ℹ Input `..1` is `date <= (. %>% filter(blah >= 0) %>% pull(date) %>% max)`.
Как я могу фильтровать таким образом?
Ответ №1:
Вместо того, чтобы выводить, проще подмножество «дата», где » бла » больше 0, и создать логическое с date
library(dplyr)
mydf %>%
filter(date <= max(date[blah >0]))
Ответ №2:
Используя эти случайные данные:
set.seed(42)
mydf <- data.frame(
date = seq(as.Date('2021-01-01'), as.Date('2021-01-20'), by = 'days'),
blah = rnorm(20, 0),
y = LETTERS[1:20]
)
mydf
# date blah y
# 1 2021-01-01 1.37095845 A
# 2 2021-01-02 -0.56469817 B
# 3 2021-01-03 0.36312841 C
# 4 2021-01-04 0.63286260 D
# 5 2021-01-05 0.40426832 E
# 6 2021-01-06 -0.10612452 F
# 7 2021-01-07 1.51152200 G
# 8 2021-01-08 -0.09465904 H
# 9 2021-01-09 2.01842371 I
# 10 2021-01-10 -0.06271410 J
# 11 2021-01-11 1.30486965 K
# 12 2021-01-12 2.28664539 L
# 13 2021-01-13 -1.38886070 M
# 14 2021-01-14 -0.27878877 N
# 15 2021-01-15 -0.13332134 O
# 16 2021-01-16 0.63595040 P
# 17 2021-01-17 -0.28425292 Q
# 18 2021-01-18 -2.65645542 R
# 19 2021-01-19 -2.44046693 S
# 20 2021-01-20 1.32011335 T
Можно сделать:
mydf %>%
filter(row_number() <= which.max(blah)) %>%
pull(date)
# [1] "2021-01-01" "2021-01-02" "2021-01-03" "2021-01-04" "2021-01-05" "2021-01-06" "2021-01-07" "2021-01-08" "2021-01-09"
# [10] "2021-01-10" "2021-01-11" "2021-01-12"
mydf %>%
filter(row_number() <= which.max(blah))
# date blah y
# 1 2021-01-01 1.37095845 A
# 2 2021-01-02 -0.56469817 B
# 3 2021-01-03 0.36312841 C
# 4 2021-01-04 0.63286260 D
# 5 2021-01-05 0.40426832 E
# 6 2021-01-06 -0.10612452 F
# 7 2021-01-07 1.51152200 G
# 8 2021-01-08 -0.09465904 H
# 9 2021-01-09 2.01842371 I
# 10 2021-01-10 -0.06271410 J
# 11 2021-01-11 1.30486965 K
# 12 2021-01-12 2.28664539 L
Это предполагает, что date
это не уменьшается; если это не гарантия, то можно сделать:
mydf %>%
filter(date <= date[which.max(blah)])
# date blah y
# 1 2021-01-01 1.37095845 A
# 2 2021-01-02 -0.56469817 B
# 3 2021-01-03 0.36312841 C
# 4 2021-01-04 0.63286260 D
# 5 2021-01-05 0.40426832 E
# 6 2021-01-06 -0.10612452 F
# 7 2021-01-07 1.51152200 G
# 8 2021-01-08 -0.09465904 H
# 9 2021-01-09 2.01842371 I
# 10 2021-01-10 -0.06271410 J
# 11 2021-01-11 1.30486965 K
# 12 2021-01-12 2.28664539 L
Ответ №3:
Я заставил его работать, заключив фигурные скобки вокруг точки:
mydf %>% filter(date <= ({.} %>% filter(blah > 0) %>% pull(date) %>% max))
Комментарии:
1. Это меня смущает. «максимальное значение бла, превышающее 0» , предполагает что-то вроде
which.max(blah[blah>0])
(что, учитывая вероятное наличие положительных чисел, вероятно, совпадает сwhich.max(blah)
). Однако вы используете его толькоmax
на самомdate
поле.2. Да, я мог бы получше сформулировать это! «Min by» или «max by» или «групповой минимум или максимум» могут быть лучшими выражениями? Примените условие к одному полю (бла-бла), а затем получите минимальное или максимальное значение в другом поле (дата).