【问题标题】:Keeping group_by in tact while applying a filter within mutate in dplyr在 dplyr 的 mutate 中应用过滤器时保持 group_by 完好无损
【发布时间】:2020-11-16 22:19:47
【问题描述】:

我正在尝试在 mutate 中应用过滤器,但我还没有找到正确的方法来应用过滤器,同时保持数据框分组完好无损。

这是一个简单的可重现示例:

# Sample data
my_dates = seq(as.Date("2020/1/1"), by = "month", length.out = 6) 
grp      = c(rep("A",3), rep("B", 3))
x        = c(2,4,6,8,10,12)

my_df <- data.frame(my_dates, grp, x)

    my_dates grp  x
1 2020-01-01   A  2
2 2020-02-01   A  4
3 2020-03-01   A  6
4 2020-04-01   B  8
5 2020-05-01   B 10
6 2020-06-01   B 12


# Pick a max date for which the data will be filtered
max_date <- "2020-05-01"


# Try to get the average by group, after filtering out the max date included
filt_data  <- my_df %>% 
  group_by(grp) %>% 
  mutate(included_data = my_dates < max_date,
         my_mean       = mean(filter(., my_dates < max_date)$x)
  )


# A tibble: 6 x 5
# Groups:   grp [2]
  my_dates   grp       x included_data my_mean
  <date>     <fct> <dbl> <lgl>           <dbl>
1 2020-01-01 A         2 TRUE                5
2 2020-02-01 A         4 TRUE                5
3 2020-03-01 A         6 TRUE                5
4 2020-04-01 B         8 TRUE                5
5 2020-05-01 B        10 FALSE               5
6 2020-06-01 B        12 FALSE               5

我希望得到的输出是这样的,其中 A 组 包含数据 的平均值 = 平均值 (2,4,6) = 4 和 的平均值>包含 B 组的数据 = mean(8) = 8:

  my_dates   grp       x included_data my_mean
  <date>     <fct> <dbl> <lgl>           <dbl>
1 2020-01-01 A         2 TRUE                4
2 2020-02-01 A         4 TRUE                4
3 2020-03-01 A         6 TRUE                4
4 2020-04-01 B         8 TRUE                8
5 2020-05-01 B        10 FALSE               8
6 2020-06-01 B        12 FALSE               8

我不确定正确的变异和过滤器会是什么,因此感谢您的帮助,并解释了为什么上述内容无法按预期工作。

谢谢!

【问题讨论】:

    标签: r filter dplyr


    【解决方案1】:

    在这里,最好使用 'included_data' 中的索引来子集 'x' 列,而不是做另一个 filter

    library(dplyr)
    my_df %>% 
         group_by(grp) %>%
         mutate(included_data = my_dates < max_date, 
                 my_mean = mean(x[included_data])) %>%
         ungroup
    

    -输出

    # A tibble: 6 x 5
    #  my_dates   grp       x included_data my_mean
    #  <date>     <chr> <dbl> <lgl>           <dbl>
    #1 2020-01-01 A         2 TRUE                4
    #2 2020-02-01 A         4 TRUE                4
    #3 2020-03-01 A         6 TRUE                4
    #4 2020-04-01 B         8 TRUE                8
    #5 2020-05-01 B        10 FALSE               8
    #6 2020-06-01 B        12 FALSE               8
    

    关于为什么 OP 的代码不起作用,. 是完整数据集,它是从完整数据而不是分组数据中提取子集。我们可以使用cur_data() 代替.

    my_df %>%
        group_by(grp) %>%
        mutate(included_data = my_dates < max_date, 
        my_mean = mean(filter(cur_data(), my_dates < max_date)$x)) %>% 
        ungroup
    # A tibble: 6 x 5
    #  my_dates   grp       x included_data my_mean
    #  <date>     <chr> <dbl> <lgl>           <dbl>
    #1 2020-01-01 A         2 TRUE                4
    #2 2020-02-01 A         4 TRUE                4
    #3 2020-03-01 A         6 TRUE                4
    #4 2020-04-01 B         8 TRUE                8
    #5 2020-05-01 B        10 FALSE               8
    #6 2020-06-01 B        12 FALSE               8
    

    【讨论】:

    • 啊,谢谢!一个小评论,你可以消除你的“手段”之一:my_mean = mean(x[included_data]))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 2020-03-13
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多