【问题标题】:custom grouped dplyr function (sample_n)自定义分组 dplyr 函数 (sample_n)
【发布时间】:2019-09-04 16:18:05
【问题描述】:

我正在尝试以分组方式将采样函数应用于数据帧,它应该从每个组中采样 n 个样本,如果组大小小于 n,则为所有组成员

使用dplyr,我第一次尝试

library(dplyr)
mtcars %>% group_by(cyl) %>% sample_n(2)

这在 n 小于所有组大小时有效,但当我选择大于组大小的 n 时不会占用整个组(请注意,其中一个 cyl 组中有 7 辆汽车):

mtcars %>% group_by(cyl) %>% sample_n(8)
Error: `size` must be less or equal than 7 (size of data), 
set `replace` = TRUE to use sampling with replacement

我试图通过创建一个适应的 group_n 函数来解决这个问题,如下所示:

sample_n_or_all <- function(tbl, n) {
  if (nrow(tbl) < n)return(tbl)
  sample_n(tbl, n)
}

但是使用我的自定义函数 (mtcars %&gt;% group_by(cyl) %&gt;% sample_n_or_all(8)) 会产生同样的错误。

有什么建议可以让我调整我的功能,以便将其应用于每个组?或者问题的其他解决方案?

【问题讨论】:

    标签: r dplyr sample


    【解决方案1】:

    我们可以检查组中的行数,并相应地将值传递给@ 987654321。

    library(dplyr)
    n <- 8
    
    temp <- mtcars %>% group_by(cyl) %>% sample_n(if(n() < n) n() else n) 
    temp
    
    #    mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
    #   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    # 1  21.4     4 121     109  4.11  2.78  18.6     1     1     4     2
    # 2  27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
    # 3  24.4     4 147.     62  3.69  3.19  20       1     0     4     2
    # 4  22.8     4 108      93  3.85  2.32  18.6     1     1     4     1
    # 5  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
    # 6  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
    # 7  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
    # 8  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
    # 9  21       6 160     110  3.9   2.62  16.5     0     1     4     4
    #10  17.8     6 168.    123  3.92  3.44  18.9     1     0     4     4
    # … with 13 more rows
    

    我们可以在该组之后检查每个组中的行号。

    table(temp$cyl)
    
    #4 6 8 
    #8 7 8 
    
    table(mtcars$cyl)
    
    # 4  6  8 
    #11  7 14 
    

    【讨论】:

    • 此解决方案更好:它不需要额外的功能定义! span>
    • 好奇,可以在这里@ 987654324或者长度不同? span>
    • @NelsonGon ifelse 也可以工作 mtcars %&gt;% group_by(cyl) %&gt;% sample_n(ifelse(n() &lt; n, n(),n)) 但由于我们只有一个条件可以检查每个组,我更喜欢 if
    【解决方案2】:

    我们可以在不使用pmin

    的逻辑条件
    library(dplyr)
    tmp <- mtcars %>%
             group_by(cyl) %>%
             sample_n(pmin(n(), n))
    # A tibble: 23 x 11
    # Groups:   cyl [3]
    #     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
    #   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    # 1  33.9     4  71.1    65  4.22  1.84  19.9     1     1     4     1
    # 2  27.3     4  79      66  4.08  1.94  18.9     1     1     4     1
    # 3  21.4     4 121     109  4.11  2.78  18.6     1     1     4     2
    # 4  30.4     4  75.7    52  4.93  1.62  18.5     1     1     4     2
    # 5  21.5     4 120.     97  3.7   2.46  20.0     1     0     3     1
    # 6  32.4     4  78.7    66  4.08  2.2   19.5     1     1     4     1
    # 7  30.4     4  95.1   113  3.77  1.51  16.9     1     1     5     2
    # 8  26       4 120.     91  4.43  2.14  16.7     0     1     5     2
    # 9  17.8     6 168.    123  3.92  3.44  18.9     1     0     4     4
    #10  21       6 160     110  3.9   2.62  16.5     0     1     4     4
    # … with 13 more rows
    

    -检查

    table(tmp$cyl)
    # 4 6 8 
    # 8 7 8 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多