r-如何访问组ID进行分组筛选操作



我有一个数据框架,其中包含三个组的日期和相关值,如下所示。

library(lubridate)
library(magrittr)
library(dplyr)
data <-
data.frame(group = rep(c("a", "b", "c"), each = 5),
date = rep(seq(ymd(20200101), ymd(20200105), by = 1),
times = 3),
value = runif(15))

我想执行分组过滤操作,以便按日期提取数据的子集,其中开始日期因组而异。

start_date <- list(a = ymd(20200102), b = ymd(20200104), c = ymd(20200103))

我想用组名索引到开始日期列表中。我尝试按如下操作,但收到一条错误消息。

data %>%
group_by(group) %>%
filter(date >= start_date[[group]]) 
Error in app$vspace(new_style$`margin-top` %||% 0) :
attempt to apply non-function

我做错了什么

(上述过程的另一种选择是将开始日期设置为数据帧,将数据帧连接到data,并执行未分组的筛选。这可以按预期工作,但(在我看来(不太优雅,出于其他原因,我更喜欢将开始日期保留为列表。(

start_date_2 <- 
data.frame(group = c("a", "b", "c"), 
start_date = c(ymd(20200102), ymd(20200104), c = ymd(20200103)))
data %>%
left_join(start_date_2, by = "group") %>%
filter(date >= start_date) %>%
select(-start_date)

我们可以使用cur_group()访问当前组的名称。这给了我们一个tibble,每个组都是包含当前组名的列,所以我们需要用$group对其进行子集设置。

library(dplyr)
data %>%
group_by(group) %>%
filter(date >= start_date[[cur_group()$group]])
#> # A tibble: 9 x 3
#> # Groups:   group [3]
#>   group date        value
#>   <chr> <date>      <dbl>
#> 1 a     2020-01-02 0.225 
#> 2 a     2020-01-03 0.345 
#> 3 a     2020-01-04 0.110 
#> 4 a     2020-01-05 0.0951
#> 5 b     2020-01-04 0.356 
#> 6 b     2020-01-05 0.345 
#> 7 c     2020-01-03 0.0973
#> 8 c     2020-01-04 0.344 
#> 9 c     2020-01-05 0.418

创建于2022-03-29由reprex包(v0.3.0(

我们可以使用purrr:

library(lubridate)
library(magrittr)
library(dplyr)
library(purrr)
data %>% 
group_split(group) %>% 
map2(., start_date, ~ filter(.x , date >= .y)) %>% 
bind_rows()
#> # A tibble: 9 x 3
#>   group date        value
#>   <fct> <date>      <dbl>
#> 1 a     2020-01-02 0.0756
#> 2 a     2020-01-03 0.0535
#> 3 a     2020-01-04 0.338 
#> 4 a     2020-01-05 0.332 
#> 5 b     2020-01-04 0.992 
#> 6 b     2020-01-05 0.356 
#> 7 c     2020-01-03 0.751 
#> 8 c     2020-01-04 0.949 
#> 9 c     2020-01-05 0.778

我们可以使用非等连接

library(data.table)
setDT(data)[data.table(date = do.call(c, start_date), 
group = names(start_date)), on = .(group, date >= date)]
group       date       value
<char>     <Date>       <num>
1:      a 2020-01-02 0.003896343
2:      a 2020-01-02 0.052198616
3:      a 2020-01-02 0.866560180
4:      a 2020-01-02 0.576245169
5:      b 2020-01-04 0.531409336
6:      b 2020-01-04 0.383936672
7:      c 2020-01-03 0.041919498
8:      c 2020-01-03 0.363742695
9:      c 2020-01-03 0.856596967

另一个选项可能是:

data %>%
filter(date >= start_date[match(group, names(start_date))])
group       date      value
1     a 2020-01-02 0.29910439
2     a 2020-01-03 0.08603731
3     a 2020-01-04 0.78913465
4     a 2020-01-05 0.40025848
5     b 2020-01-04 0.87568202
6     b 2020-01-05 0.21065155
7     c 2020-01-03 0.47403618
8     c 2020-01-04 0.74996630
9     c 2020-01-05 0.08386366

最新更新