【问题标题】:sample 1 element from each list in nested list in R to create groups of samples从 R 的嵌套列表中的每个列表中采样 1 个元素以创建样本组
【发布时间】:2020-09-20 07:37:46
【问题描述】:

我有一个嵌套的列表列表,其中每个条目都包含一个值列表。

我希望从每个嵌套列表中抽取一个元素并创建一组元素。

这样的列表的一个例子是:

xxx_ <- list(c(13L, 15L, 5L, 6L), c(7L, 20L, 14L, 18L, 1L, 8L, 17L), 
    c(9L, 11L, 4L, 12L), c(16L, 19L, 10L, 2L, 3L))

我正在执行以下操作,但感觉需要一种更简单的方法来对该列表列表进行采样。

l_sample <- list()
for(g in 1:10) {
  l <- c()
  for(i in 1:4) {
    l <- c(l,sample(xxx_[[i]], 1))
  }
  l_sample[[g]] <- l
}

结果如下:

> l_sample
[[1]]
[1] 15  7 12 10

[[2]]
[1] 6 1 4 2

[[3]]
[1] 13 18  4 19

[[4]]
[1]  6 17  4  2

[[5]]
[1] 15 18  4  3

[[6]]
[1] 13 18  9  3

[[7]]
[1]  6 17 12 19

[[8]]
[1]  5 20  9 19

[[9]]
[1]  5 18  9 10

[[10]]
[1] 13  7  9  3

我还想将每个样本作为新行附加到数据框,其中每个元素都在新列中,但我做不到。

类似:

> df
  g1 g2 g3 g4
1 15  7 12 10
2 6 1 4 2
...

不胜感激。

【问题讨论】:

    标签: r random nested-lists sample


    【解决方案1】:

    您可以使用 sapply 从每个列表中选择 1 个元素,然后使用 replicate 重复 10 次。

    t(replicate(10, sapply(xxx_, sample, 1)))
    
    #      [,1] [,2] [,3] [,4]
    # [1,]   15    7    9   10
    # [2,]   15    8    9    3
    # [3,]   13   14    4   19
    # [4,]    5   14   12   10
    # [5,]   13   20    9    3
    # [6,]    5   18   12   16
    # [7,]    5    1   11    2
    # [8,]    6   14   11   19
    # [9,]    5    8   12    3
    #[10,]    5   17    4    2
    

    【讨论】:

      【解决方案2】:

      如果您想从每个嵌套列表中采样 10 次,则可以使用 sapplysize = 10replace = TRUE 像这样传递给 sample

      set.seed(1)
      sapply(xxx_, sample, 10, TRUE)
      #R>       [,1] [,2] [,3] [,4]
      #R>  [1,]   13   14    9   19
      #R>  [2,]    6   14    4   16
      #R>  [3,]    5    7    9    2
      #R>  [4,]   13    1    9   16
      #R>  [5,]   15    1    9    2
      #R>  [6,]   13   20    9   10
      #R>  [7,]    5    8   11   19
      #R>  [8,]    5    8    9   19
      #R>  [9,]   15   20    9    2
      #R> [10,]   15   17   11    2
      

      10更改为您要进行的抽奖次数。

      这种方法还具有保留名称的优点。例如,假设您的数据如下所示:

      xxx_ <- list(
        g1 = c(13L, 15L, 5L, 6L ), g2 = c(7L , 20L, 14L, 18L, 1L, 8L, 17L), 
        g3 = c(9L , 11L, 4L, 12L), g4 = c(16L, 19L, 10L, 2L, 3L))
      

      然后您可以按照您的要求执行以下操作来获取 data.frame:

      set.seed(1)
      as.data.frame(sapply(xxx_, sample, 10, TRUE))
      #R>    g1 g2 g3 g4
      #R> 1  13 14  9 19
      #R> 2   6 14  4 16
      #R> 3   5  7  9  2
      #R> 4  13  1  9 16
      #R> 5  15  1  9  2
      #R> 6  13 20  9 10
      #R> 7   5  8 11 19
      #R> 8   5  8  9 19
      #R> 9  15 20  9  2
      #R> 10 15 17 11  2
      

      速度

      比调用replicate快很多:

      bench::mark(
          replicate = t(replicate(10, sapply(xxx_, sample, 1))), 
          sapply    = sapply(xxx_, sample, 10, TRUE), 
          min_time = 1, check = FALSE)
      #R> # A tibble: 2 x 13
      #R>   expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result memory                  time              gc                   
      #R>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> <list> <list>                  <list>            <list>               
      #R> 1 replicate   213.3µs    235µs     4071.   100.3KB     45.7  3384    38      831ms <NULL> <Rprofmem[,3] [43 × 3]> <bch:tm [3,422]>  <tibble [3,422 × 3]> 
      #R> 2 sapply       22.4µs   25.2µs    38417.    10.4KB     46.2  9988    12      260ms <NULL> <Rprofmem[,3] [6 × 3]>  <bch:tm [10,000]> <tibble [10,000 × 3]>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多