【问题标题】:Select subset of unique random records in R在 R 中选择唯一随机记录的子集
【发布时间】:2014-12-02 16:15:36
【问题描述】:

我想从数据框中选择 n 个随机记录的子集,但我想要基于列的唯一值。例如,从数据集中

X1 X2
1  4
1  5
1  6
2  44
2  55
3  444
3  555
3  666
3  777

对于 n=3,我不想要这样的东西:

X1  X2
 3 777
 3 555
 2  55

其中两条记录来自同一个种子 X1 = 3 但我想要类似的东西:

X1  X2
 1  5
 2  44
 3  555

我该怎么做?

我尝试了以下方法:

df <- data.frame(matrix(c(1,1,1,2,2,3,3,3,3,4,4,4,5,5,5,5,5,4,5,6,44,55,444,555,666,777,4444,5555,6666,10,20,30,40,50),nrow=17,ncol=2))
df.colnames = c("x1","x2")
df[sample(nrow(df),3),]

但它似乎并没有给我想要的东西。如何调整样本以获得我想要的?或者我应该使用不同的函数进行子集化

编辑请注意,我的 df 将有大约 5000 万条记录,我可能希望从中抽取 100 万条记录。 (如 1 m 个唯一数据点)。哪种方法最有效?

【问题讨论】:

    标签: r random unique


    【解决方案1】:

    您可以使用我的“splitstackshape”包中的stratified 函数,如下所示:

    library(splitstackshape)
    set.seed(1) ## so you can reproduce this
    stratified(df, "X1", 1)
    #    X1  X2
    # 1:  1   4
    # 2:  2  44
    # 3:  3 666
    

    或者,您可以使用来自“dplyr”的sample_n

    library(dplyr)
    set.seed(1) ## again, just to reproduce this
    df %>% group_by(X1) %>% sample_n(1)
    # Source: local data frame [3 x 2]
    # Groups: X1
    # 
    #   X1  X2
    # 1  1   4
    # 2  2  44
    # 3  3 666
    

    关于您的说明,以下是我系统上 20M 行的一些快速计时:

    set.seed(1)
    df <- data.frame(X1 = sample(1000000, 20000000, TRUE), 
                     X2 = rnorm(20000000))
    dim(df)
    # [1] 20000000        2
    
    system.time(df %>% group_by(X1) %>% sample_n(1))
    #   user  system elapsed 
    # 39.687   0.365  40.583 
    system.time(as.data.table(df)[, list(X2=sample(X2,1)), by=X1])
    #   user  system elapsed 
    # 10.792   0.156  11.033 
    system.time(stratified(df, "X1", 1))
    #   user  system elapsed 
    # 12.351   0.455  12.895 
    

    (当然,stratified 还会为您提供其他开箱即用的功能,例如动态子集、采样与组的大小成正比等等 :-))

    【讨论】:

    • 啊,看来你更新答案时我添加了我的想法!
    【解决方案2】:

    试试

     set.seed(1)
     aggregate(X2~X1, df, sample, 1)
     #   X1  X2
     #1  1   4
     #2  2  44
     #3  3 666
    

    或使用data.table

     set.seed(1)
     setDT(df)[, list(X2=sample(X2,1)), by=X1]
     #  X1  X2
     #1:  1   4
     #2:  2  44
     #3:  3 666
    

    【讨论】:

      【解决方案3】:

      这可能是使用dplyr 的另一种方式。

      group_by(df, X1) %>%
      sample_n(1)
      
      #  X1  X2
      #1  1   5
      #2  2  55
      #3  3 777
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-27
        • 2020-08-31
        • 2010-10-02
        • 2014-08-04
        • 1970-01-01
        • 2015-10-15
        • 2016-05-09
        • 2011-04-08
        相关资源
        最近更新 更多