r - 选择最大组值 dplyr 上下的行
问题描述
我有一个时间序列数据集,其中包含许多不同的组(由组列中的行值指定)和变量列。
我想为每个组选择具有给定变量列的最小值的行,然后选择 3 行日期“高于”和“低于”(之前和之后)最小值以及最大值本身。
最终结果应为每组 7 行,最小值为第 4 行。理想情况下,我想在 dplyr 中执行此操作...
输入:
structure(list(Country = c("ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG", "ARG",
"ARG", "ARG", "ARG", "ARG", "ARG", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS", "AUS",
"AUS", "AUS", "AUS", "AUS", "AUS", "AUS"), Date = structure(c(18307,
18308, 18309, 18310, 18311, 18312, 18313, 18314, 18315, 18316,
18317, 18318, 18319, 18320, 18321, 18322, 18323, 18324, 18325,
18326, 18327, 18328, 18329, 18330, 18331, 18332, 18333, 18334,
18335, 18336, 18337, 18338, 18339, 18340, 18341, 18342, 18343,
18344, 18345, 18346, 18347, 18348, 18349, 18350, 18351, 18352,
18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360, 18361,
18307, 18308, 18309, 18310, 18311, 18312, 18313, 18314, 18315,
18316, 18317, 18318, 18319, 18320, 18321, 18322, 18323, 18324,
18325, 18326, 18327, 18328, 18329, 18330, 18331, 18332, 18333,
18334, 18335, 18336, 18337, 18338, 18339, 18340, 18341, 18342,
18343, 18344, 18345, 18346, 18347, 18348, 18349, 18350, 18351,
18352, 18353, 18354, 18355, 18356, 18357, 18358, 18359, 18360,
18361), class = "Date"), MobDecline = c(1.33333333333333, -4,
-1.66666666666667, 7, 6.66666666666667, 5.33333333333333, 7,
4, 5.66666666666667, -30.3333333333333, -32.6666666666667, 7.66666666666667,
6.33333333333333, 8, 4.33333333333333, -1.33333333333333, 8,
8, 8.33333333333333, 9.66666666666667, 12, 5.33333333333333,
1.33333333333333, 9.66666666666667, 11.6666666666667, -2.33333333333333,
8, 6.66666666666667, -14, -18.6666666666667, -14.3333333333333,
-28.3333333333333, -32.3333333333333, -33.6666666666667, -70.3333333333333,
-71.6666666666667, -75.3333333333333, -84, -84, -75.6666666666667,
-76, -74.3333333333333, -72, -74.3333333333333, -75.3333333333333,
-81, -72.6666666666667, -72.3333333333333, -70, -67.3333333333333,
-70.3333333333333, -68.3333333333333, -68.3333333333333, -67.6666666666667,
-71, 3.33333333333333, 1.66666666666667, 7.66666666666667, 6,
6.66666666666667, 7.33333333333333, 10.3333333333333, 5.33333333333333,
1.66666666666667, 8, 7.33333333333333, 7.66666666666667, 8, 11.6666666666667,
7, 3, 5.33333333333333, 7.33333333333333, 7, 5.66666666666667,
9.33333333333333, 2.66666666666667, 0.333333333333333, -8.66666666666667,
5.66666666666667, 6.33333333333333, 6, 6.66666666666667, -2.66666666666667,
-5.33333333333333, 1.33333333333333, -4.66666666666667, -7.66666666666667,
-10.6666666666667, -11.3333333333333, -16.3333333333333, -21.3333333333333,
-19.6666666666667, -31.3333333333333, -34.6666666666667, -38,
-38, -40.3333333333333, -45.3333333333333, -43.3333333333333,
-45.3333333333333, -45.6666666666667, -47.6666666666667, -45.6666666666667,
-46, -47.3333333333333, -45, -46, -45, -42.3333333333333)), row.names = c(NA,
-110L), groups = structure(list(Country = c("ARG", "AUS"), .rows = list(
1:55, 56:110)), row.names = c(NA, -2L), class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
期望的结果:
Country Date MobDecline
ARG 2020-03-19 -33.6666667
ARG 2020-03-20 -70.3333333
ARG 2020-03-21 -71.6666667
ARG 2020-03-22 -75.3333333
ARG 2020-03-23 -84.0000000
ARG 2020-03-24 -84.0000000
ARG 2020-03-25 -75.6666667
AUS 2020-03-30 -43.3333333
AUS 2020-03-31 -45.3333333
AUS 2020-04-01 -45.6666667
AUS 2020-04-02 -47.6666667
AUS 2020-04-03 -45.6666667
AUS 2020-04-04 -46.0000000
AUS 2020-04-05 -47.3333333
解决方案
我认为您的预期输出不正确:ARG
“最大值”(绝对值!)值打开2020-03-23
(和-24
),但您在它之前显示四行,在它之后显示不足的行。
试试这个:
dat %>%
group_by(Country) %>%
mutate(most = row_number() == which.max(abs(MobDecline))) %>%
filter(zoo::rollapply(most, width = 7, FUN = any, fill = FALSE))
# # A tibble: 14 x 4
# # Groups: Country [2]
# Country Date MobDecline most
# <chr> <date> <dbl> <lgl>
# 1 ARG 2020-03-20 -70.3 FALSE
# 2 ARG 2020-03-21 -71.7 FALSE
# 3 ARG 2020-03-22 -75.3 FALSE
# 4 ARG 2020-03-23 -84 TRUE
# 5 ARG 2020-03-24 -84 FALSE
# 6 ARG 2020-03-25 -75.7 FALSE
# 7 ARG 2020-03-26 -76 FALSE
# 8 AUS 2020-03-30 -43.3 FALSE
# 9 AUS 2020-03-31 -45.3 FALSE
# 10 AUS 2020-04-01 -45.7 FALSE
# 11 AUS 2020-04-02 -47.7 TRUE
# 12 AUS 2020-04-03 -45.7 FALSE
# 13 AUS 2020-04-04 -46 FALSE
# 14 AUS 2020-04-05 -47.3 FALSE
(并且most
可以删除,保留在这里进行演示)。
使用的zoo::rollapply
版本比基于重复lead
和/或的版本短得多且灵活得多lag
(否则这是解决此问题的一种方法)。
现在,这是 using abs(which.max(...))
,它都假定最大绝对值(毕竟您确实说过最大)并且将最多返回一个条目,即使在并列时也是如此。如果你需要 +/- 3 行来包含这个(所以这里再包含一行),那么我们可以尝试使用==
,但它有时会失败(R FAQ 7.31),所以我将介绍一个“容差”:
dat %>%
group_by(Country) %>%
mutate(most = MobDecline <= (min(MobDecline) + tol)) %>%
filter(zoo::rollapply(most, width = 7, FUN = any, fill = FALSE))
# # A tibble: 15 x 4
# # Groups: Country [2]
# Country Date MobDecline most
# <chr> <date> <dbl> <lgl>
# 1 ARG 2020-03-20 -70.3 FALSE
# 2 ARG 2020-03-21 -71.7 FALSE
# 3 ARG 2020-03-22 -75.3 FALSE
# 4 ARG 2020-03-23 -84 TRUE
# 5 ARG 2020-03-24 -84 TRUE
# 6 ARG 2020-03-25 -75.7 FALSE
# 7 ARG 2020-03-26 -76 FALSE
# 8 ARG 2020-03-27 -74.3 FALSE
# 9 AUS 2020-03-30 -43.3 FALSE
# 10 AUS 2020-03-31 -45.3 FALSE
# 11 AUS 2020-04-01 -45.7 FALSE
# 12 AUS 2020-04-02 -47.7 TRUE
# 13 AUS 2020-04-03 -45.7 FALSE
# 14 AUS 2020-04-04 -46 FALSE
# 15 AUS 2020-04-05 -47.3 FALSE
推荐阅读
- angular - @Input decorator not working when value changes
- uwp-xaml - Getting access violation exception only in x86 release executable using c++/winrt and xaml controls in UWP application
- angular - 无法检测到可用设备
- java - Intellij 坚持使用 javac 11.0.3 而不是 Java 7 进行编译
- php - 添加到购物车 WooCommerce 后使用参数刷新当前页面
- bash - $(command here) 和 `command here` 有什么区别
- javascript - 如何关闭打印窗口
- excel - 将文本读取为数字的公式
- javascript - 我们可以根据条件在 react.js 中的 map 中引入换行符(css)吗
- qmake - QMake / jom 强制额外的 MIDL 编译器在 RC 之前运行