【问题标题】:Sample from different data.frame来自不同data.frame的样本
【发布时间】:2020-03-25 13:09:44
【问题描述】:
 data1=data.frame("Group1" = sample(1:2,100,r=T),
                  "Group2" = sample(c('a','b'),100,r=T),
                  "V1" = sample(1:3, 100, r=T),
                  "V2" = sample(0:1, 100, r=T),
                  "V3" = sample(1:5, 100, r=T),
                  "V4" = sample(1:2, 100, r=T))


data2=data.frame("Group1"=c(1,1,2,2),
                  "Group2"=c('a','b','a','b'),
                  "Size"=c(9,7,6,10),
                  "V1"=c(NA),
                  "V2"=c(NA),
                  "V3"=c(NA),
                  "V4"=c(NA))

我有包含我的数据的“data1”。然后我有'data2',它有'Group1'和'Group2'和'Size'。 我希望将我的数据按('Group1'和'Group2')分组,并从'data1'中随机抽取一个大小为'Size'的样本来填充data2中的V1-V4。


有希望的输出看起来像这样,但 NA 值是根据 'data1' 填写的

library(dplyr);library(tidyr)
data3= data2 %>% 
  uncount(Size)

【问题讨论】:

    标签: r data.table sample


    【解决方案1】:
    library(data.table)
    setDT(data1)
    setDT(data2)
    
    # sample indices from each group
    i <- 
      data2[data1, on = .(Group1, Group2)
          ][, .(i_samp = sample(.I, Size)), by = .(Group1, Group2, Size)
          ][, i_samp]
    
    # subset to sampled indices
    merge(data1[i], data2[, .(Group1, Group2, Size)])
    
    #     Group1 Group2 V1 V2 V3 V4 Size
    #  1:      1      a  3  1  2  2    9
    #  2:      1      a  3  1  5  1    9
    #  3:      1      a  2  1  4  2    9
    #  4:      1      a  3  1  1  1    9
    #  5:      1      a  3  1  4  1    9
    #  6:      1      a  1  0  3  1    9
    #  7:      1      a  3  1  1  1    9
    #  8:      1      a  1  1  1  2    9
    #  9:      1      a  2  0  2  1    9
    # 10:      1      b  2  0  5  2    7
    # 11:      1      b  3  0  5  2    7
    # 12:      1      b  3  1  4  2    7
    # 13:      1      b  1  1  1  1    7
    # 14:      1      b  1  1  4  1    7
    # 15:      1      b  1  0  1  1    7
    # 16:      1      b  1  0  3  1    7
    # 17:      2      a  2  0  5  1    6
    # 18:      2      a  1  0  5  1    6
    # 19:      2      a  3  1  1  2    6
    # 20:      2      a  1  0  2  1    6
    # 21:      2      a  3  1  1  2    6
    # 22:      2      a  1  1  3  2    6
    # 23:      2      b  3  0  2  1   10
    # 24:      2      b  2  1  5  1   10
    # 25:      2      b  3  0  1  1   10
    # 26:      2      b  3  1  2  1   10
    # 27:      2      b  2  0  5  1   10
    # 28:      2      b  2  0  2  1   10
    # 29:      2      b  2  0  2  2   10
    # 30:      2      b  1  0  1  1   10
    # 31:      2      b  3  0  5  1   10
    # 32:      2      b  3  0  5  1   10
    #     Group1 Group2 V1 V2 V3 V4 Size
    

    使用的输入数据:

    data1=data.frame("Group1" = sample(1:2,100,r=T),
                      "Group2" = sample(c('a','b'),100,r=T),
                      "V1" = sample(1:3, 100, r=T),
                      "V2" = sample(0:1, 100, r=T),
                      "V3" = sample(1:5, 100, r=T),
                      "V4" = sample(1:2, 100, r=T))
    
    
    data2=data.frame("Group1"=c(1,1,2,2),
                      "Group2"=c('a','b','a','b'),
                      "Size"=c(9,7,6,10),
                      "V1"=c(NA),
                      "V2"=c(NA),
                      "V3"=c(NA),
                      "V4"=c(NA))
    

    这是一个更加参数化的版本,您可以在其中明确设置要填充的列以及连接两个表的键

    fill_key <- c('Group1', 'Group2')
    columns_to_fill <- paste0('V', 1:4)
    
    # sample indices from each group
    i <- 
      data2[data1, on = (fill_key)
          ][, .(i_samp = sample(.I, Size)), by = c(fill_key, 'Size')
          ][, i_samp]
    
    
    # subset to sampled indices
    merge(data1[i, c(fill_key, columns_to_fill), with = FALSE], 
          data2[, c(fill_key, 'Size'), with = FALSE])
    

    【讨论】:

    • 我不确定这是否完全正确。我希望从 data1 中采样并将值填充到 data2 中。也就是说,根据group和data1在data2中填写'NA'。
    • 据我所知,这里的输出和你描述的一样。
    • 根据新数据更新。
    • V1 实际上与您的列名无关,它只是 data.table 为示例索引列提供的默认名称,因为我没有费心为该列命名。不是很清楚,所以我重写了它以避免混淆使用V1。我还添加了一个版本,您可以在其中设置要填充的列。
    • 如果您在运行代码之前未将数据转换为data.table,则会发生这种情况。将数据转换为 data.table 的方式是运行 setDT(yourdata)
    【解决方案2】:

    一个dplyr 选项可能是:

    data1 %>%
     left_join(data2 %>%
                select(-starts_with("V"))) %>%
     group_by(Group1, Group2) %>%
     sample_n(Size) 
    
       Group1 Group2    V1    V2    V3    V4  Size
        <dbl> <fct>  <int> <int> <int> <int> <dbl>
     1      1 a          1     1     1     2     9
     2      1 a          3     0     3     2     9
     3      1 a          2     0     3     2     9
     4      1 a          1     1     2     1     9
     5      1 a          2     1     2     2     9
     6      1 a          2     0     5     2     9
     7      1 a          1     0     1     2     9
     8      1 a          3     0     5     2     9
     9      1 a          1     0     5     1     9
    10      1 b          2     0     1     1     7
    11      1 b          2     1     3     1     7
    12      1 b          3     1     4     2     7
    13      1 b          1     1     1     1     7
    14      1 b          2     1     2     2     7
    15      1 b          1     1     1     2     7
    16      1 b          1     1     2     1     7
    17      2 a          3     1     5     1     6
    18      2 a          1     0     5     1     6
    19      2 a          1     0     1     1     6
    20      2 a          2     0     5     1     6
    21      2 a          3     0     1     1     6
    22      2 a          2     1     4     1     6
    23      2 b          3     0     2     1    10
    24      2 b          1     1     5     1    10
    25      2 b          3     1     1     1    10
    26      2 b          3     1     4     1    10
    27      2 b          1     0     4     2    10
    28      2 b          3     1     1     2    10
    29      2 b          2     1     4     1    10
    30      2 b          1     0     1     1    10
    31      2 b          2     1     4     2    10
    32      2 b          2     1     5     2    10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2015-03-21
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      相关资源
      最近更新 更多