删除日期取决于特定ID的行

时间:2019-02-14 15:49:59

标签: r subset nested-loops

基本上,我有一个包含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特定的

1 个答案:

答案 0 :(得分:0)

这是你的追求吗?

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

您还可以为之前/之后创建单独的列,例如:

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

另一方面,您可以在您的环境中创建两个名为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个数据帧的列表,因此我们需要将它们放入全局环境,因此首先我们为每个数据帧分配名称,然后将它们变成“适当的”数据帧。

输出:

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