删除日期以特定 ID 为条件的行

Removing rows with dates conditional to specific IDs

基本上,我有一个包含 ID、日期、VolumeX 和 VolumeY 的数据框。

我想将 VolumeX 数据帧拆分为特定于 ID 的 VolumeY 最大日期之前和之后。

例如。

df 看起来像(有许多不同的 ID):

ID  Date            VolX   VolY
1   2018 - 02- 01   5      -
1   2018 - 03- 01   6      -
1   2018 - 08- 01   3      -
1   2018 - 10- 01   1      -
1   2017 - 02- 01   -      1
1   2014 - 10- 01   -      0
1   2014 - 11- 01   -      5
1   2018 - 02- 01   -      0 

因此,对于每个 ID 的最大 VolY 日期,我想将数据框分成两部分:每个 ID 的该日期之前和之后,以便对 VolY 最大日期之前和之后的 VolX 求和。

这似乎需要某种嵌套的 for 循环。我能够提取最大日期和总体积...只是很难选择特定于 ID

这就是你想要的吗?

library(dplyr)

df %>%
  replace(., . == "-", NA) %>%
  mutate(Date = as.Date(gsub("\s", "", Date))) %>%
  mutate_at(vars(VolX, VolY), as.numeric) %>%
  group_by(ID, Before_After = cumsum(c(0, lag(+(Date == max(Date)))[-1]))) %>%
  mutate(
    sum_Volx = sum(VolX[Date != max(Date)], na.rm = T),
    sum_VolY = sum(VolY[Date != max(Date)], na.rm = T)
  ) %>% ungroup() %>% select(-Before_After)

输出:

# A tibble: 8 x 6
     ID Date        VolX  VolY sum_Volx sum_VolY
  <int> <date>     <dbl> <dbl>    <dbl>    <dbl>
1     1 2018-02-01     5    NA       14        0
2     1 2018-03-01     6    NA       14        0
3     1 2018-08-01     3    NA       14        0
4     1 2018-10-01     1    NA       14        0
5     1 2017-02-01    NA     1        0        6
6     1 2014-10-01    NA     0        0        6
7     1 2014-11-01    NA     5        0        6
8     1 2018-02-01    NA     0        0        6

您还可以为 before/after 创建单独的列,如下所示:

df %>%
  replace(., . == "-", NA) %>%
  mutate_at(vars(VolX, VolY), as.numeric) %>%
  group_by(ID) %>%
  mutate(
    Date = as.Date(gsub("\s", "", Date)),
    Before_After = cumsum(c(0, lag(+(Date == max(Date)))[-1])),
    sum_Volx_Before = sum(VolX[Date != max(Date) & Before_After == 0], na.rm = T),
    sum_VolY_Before = sum(VolY[Date != max(Date) & Before_After == 0], na.rm = T),
    sum_Volx_After = sum(VolX[Date != max(Date) & Before_After == 1], na.rm = T),
    sum_VolY_After = sum(VolY[Date != max(Date) & Before_After == 1], na.rm = T)
  ) %>% ungroup() %>% select(-Before_After)

输出:

# A tibble: 8 x 8
     ID Date        VolX  VolY sum_Volx_Before sum_VolY_Before sum_Volx_After sum_VolY_After
  <int> <date>     <dbl> <dbl>           <dbl>           <dbl>          <dbl>          <dbl>
1     1 2018-02-01     5    NA              14               0              0              6
2     1 2018-03-01     6    NA              14               0              0              6
3     1 2018-08-01     3    NA              14               0              0              6
4     1 2018-10-01     1    NA              14               0              0              6
5     1 2017-02-01    NA     1              14               0              0              6
6     1 2014-10-01    NA     0              14               0              0              6
7     1 2014-11-01    NA     5              14               0              0              6
8     1 2018-02-01    NA     0              14               0              0              6

另一方面,您可以在您的环境中创建 2 个单独的新数据框,命名为 BeforeAfter,从字面上排除最大日期并汇总信息,如下所示:

df_list <- df %>%
  replace(., . == "-", NA) %>%
  mutate_at(vars(VolX, VolY), as.numeric) %>%
  group_by(ID) %>%
  mutate(
    Date = as.Date(gsub("\s", "", Date)),
    Before_After = cumsum(c(0, lag(+(Date == max(Date)))[-1]))
  ) %>%
  filter(!Date == max(Date)) %>%
  group_by(ID, Before_After) %>%
  summarise(
    sum_VolX = sum(VolX, na.rm = T),
    sum_VolY = sum(VolY, na.rm = T)
  ) %>%
  split(., .$Before_After)

names(df_list) <- c("Before", "After")
list2env(df_list, envir = .GlobalEnv)

让我们一一分析:

  • 首先我们 replace -NA 签名(不是严格需要,只是为了避免以后出错);
  • 然后我们将VolXVolY转化为数字;
  • 然后我们按 ID 分组,以便所有内容分别应用于每个组;
  • 然后我们将 Date 转换为适当的 Date 格式;
  • 然后是关键部分:我们计算标志 Before_After 列,如果在前一行中观察到最大日期,我们首先用 1 标记;之后我们计算该列的累积和,以便此事件之前的所有内容均为 0,之后的所有内容均为 1;
  • 然后我们过滤掉最大值Date;
  • 我们按 IDBefore_After 指标再次分组;
  • 我们使用 summarise 缩小数据框,使其仅包含各列的总和;
  • 我们通过在 Before_After 列上拆分将数据框变成 2 个不同的数据框;
  • 因为得到的结果是2个数据框的列表,我们需要把它们放到全局环境中,所以我们先给每个数据框起个名字,然后我们把它们变成'proper'个数据框。

输出:

Before

# A tibble: 1 x 4
# Groups:   ID [1]
     ID Before_After sum_VolX sum_VolY
  <int>        <dbl>    <dbl>    <dbl>
1     1            0       14        0

After

# A tibble: 1 x 4
# Groups:   ID [1]
     ID Before_After sum_VolX sum_VolY
  <int>        <dbl>    <dbl>    <dbl>
1     1            1        0        6

注意0对应Before,1对应After