删除日期以特定 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 个单独的新数据框,命名为 Before
和 After
,从字面上排除最大日期并汇总信息,如下所示:
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
签名(不是严格需要,只是为了避免以后出错);
- 然后我们将
VolX
和VolY
转化为数字;
- 然后我们按
ID
分组,以便所有内容分别应用于每个组;
- 然后我们将
Date
转换为适当的 Date
格式;
- 然后是关键部分:我们计算标志
Before_After
列,如果在前一行中观察到最大日期,我们首先用 1
标记;之后我们计算该列的累积和,以便此事件之前的所有内容均为 0,之后的所有内容均为 1;
- 然后我们过滤掉最大值
Date
;
- 我们按
ID
和 Before_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
。
基本上,我有一个包含 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 个单独的新数据框,命名为 Before
和 After
,从字面上排除最大日期并汇总信息,如下所示:
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
签名(不是严格需要,只是为了避免以后出错); - 然后我们将
VolX
和VolY
转化为数字; - 然后我们按
ID
分组,以便所有内容分别应用于每个组; - 然后我们将
Date
转换为适当的Date
格式; - 然后是关键部分:我们计算标志
Before_After
列,如果在前一行中观察到最大日期,我们首先用1
标记;之后我们计算该列的累积和,以便此事件之前的所有内容均为 0,之后的所有内容均为 1; - 然后我们过滤掉最大值
Date
; - 我们按
ID
和Before_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
。