【问题标题】:Create new columns with quantiles from a group in r从 r 中的组中创建带有分位数的新列
【发布时间】:2019-10-15 06:27:54
【问题描述】:

我想按组包含分位数为 1 y 3 的新列

我有这个数据框:

d <- data.frame(date = c("2017-02-23", "2017-02-22", "2017-02-23", "2017-02-23","2018-02-22", "2018-02-22"), 
var1 = c(1,3,6,7,8,5), 
var2 = c(1,3,18,15,25,5)) 

我想有两个新专栏Q1var1Q1var2Q1var1Q1var2,比如:

d = d %>% group_by(date) %>% mutate(Q1var1 = quantile(var1,prob = 0.25,na.rm = TRUE))
d = d %>% group_by(date) %>% mutate(Q1var2 = quantile(var1,prob = 0.25,na.rm = TRUE))
d = d %>% group_by(date) %>% mutate(Q3var1 = quantile(var1,prob = 0.75,na.rm = TRUE))
d = d %>% group_by(date) %>% mutate(Q3var2 = quantile(var1,prob = 0.75,na.rm = TRUE))

但以更快的方式

【问题讨论】:

    标签: r group-by quantile


    【解决方案1】:

    一个选项是按“日期”分组,然后使用mutate_at 在多个列上应用函数,将quantile 输出转换为包裹在list 中的tibble,然后再转换为unnest

    library(tidyverse)
    d %>% 
      group_by(date) %>%
      mutate_at(vars(var1, var2), list(Qs = ~ 
         list(as_tibble(as.list(quantile(., prob = c(0.25, 0.75),
             na.rm = TRUE )))))) %>%
      unnest
    # A tibble: 6 x 7
    # Groups:   date [3]
    #  date        var1  var2 `25%` `75%` `25%1` `75%1`
    #  <fct>      <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>
    #1 2017-02-23     1     1  3.5   6.5       8   16.5
    #2 2017-02-22     3     3  3     3         3    3  
    #3 2017-02-23     6    18  3.5   6.5       8   16.5
    #4 2017-02-23     7    15  3.5   6.5       8   16.5
    #5 2018-02-22     8    25  5.75  7.25     10   20  
    #6 2018-02-22     5     5  5.75  7.25     10   20  
    

    或者data.table

    library(data.table)
    nm1 <-  paste0("Q_", rep(c("var1", "var2"), each = 2), c(".Q25", ".Q75"))
    setDT(d)[, (nm1) := unlist(lapply(.SD, function(x) 
       as.list(quantile(x, prob = c(0.25, 0.75)))), recursive = FALSE),
              date, .SDcols = var1:var2]
    d
    #         date var1 var2 Q_var1.Q25 Q_var1.Q75 Q_var2.Q25 Q_var2.Q75
    #1: 2017-02-23    1    1       3.50       6.50          8       16.5
    #2: 2017-02-22    3    3       3.00       3.00          3        3.0
    #3: 2017-02-23    6   18       3.50       6.50          8       16.5
    #4: 2017-02-23    7   15       3.50       6.50          8       16.5
    #5: 2018-02-22    8   25       5.75       7.25         10       20.0
    #6: 2018-02-22    5    5       5.75       7.25         10       20.0
    

    【讨论】:

      【解决方案2】:

      这是一个基本解决方案,以防万一。首先,我定义了数据框。

      # Original data frame
      d <- data.frame(date = c("2017-02-23", "2017-02-22", "2017-02-23", "2017-02-23","2018-02-22", "2018-02-22"), 
                      var1 = c(1,3,6,7,8,5), 
                      var2 = c(1,3,18,15,25,5)) 
      

      接下来,我定义了一个计算分位数并将它们绑定到原始数​​据的函数。

      # Function to calculate quantiles
      foo <- function(x){
        q <- quantile(x, prob = c(0.25, 0.75), na.rm = TRUE)
        data.frame(x, q25 = q[1], q75 = q[2], row.names = NULL)
      }
      

      我将函数应用于每个日期的每个变量,然后rbind 将结果放入单个数据框中。

      # The horror...
      d2 <- do.call(rbind, lapply(levels(d$date), 
                                  function(x) data.frame(date = x, lapply(d[d$date == x, names(d) != "date"], foo))))
      

      这给出了以下内容。

      # print results
      d2
      #>         date var1.x var1.q25 var1.q75 var2.x var2.q25 var2.q75
      #> 1 2017-02-22      3     3.00     3.00      3        3      3.0
      #> 2 2017-02-23      1     3.50     6.50      1        8     16.5
      #> 3 2017-02-23      6     3.50     6.50     18        8     16.5
      #> 4 2017-02-23      7     3.50     6.50     15        8     16.5
      #> 5 2018-02-22      8     5.75     7.25     25       10     20.0
      #> 6 2018-02-22      5     5.75     7.25      5       10     20.0
      

      reprex package (v0.3.0) 于 2019 年 5 月 29 日创建

      与@akrun 的(更好的)解决方案不同,这种方法的一个问题是它会重新排序您的数据框。

      【讨论】:

        猜你喜欢
        • 2021-12-16
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        • 2018-04-09
        • 2020-09-18
        • 1970-01-01
        • 2023-01-12
        相关资源
        最近更新 更多