【问题标题】:How do I write a loop to random sample from multiple subsets of data?如何编写循环以从多个数据子集中随机采样?
【发布时间】:2014-01-08 20:22:25
【问题描述】:

我有一个(可能很简单)我想不通的问题。

我想编写一个循环(或使用 mapply 或 ddply?)从多个数据子集中的每一个中随机采样三个值,并找到该随机样本的平均值并将其放入数据框中。

例如,这里是一小部分数据:

    BayStation DIN Year
1        60069 0.0090 1998     
2        60069 0.0060 1998     
3        60069 0.0100 1998     
4        60069 0.0020 1998     
5        60069 0.0140 1998     
6        60069 0.0110 1998     
7        60081 0.0140 1998     
8        60081 0.0140 1998     
9        60081 0.0060 1998     
10       60081 0.0020 1998     
11       60081 0.0250 1998     
12       60081 0.0140 1998     
13       60081 0.0110 1998     

我想按 BayStation 进行子集化,为每个 BayStation 随机抽取三个 DIN 值,然后计算平均值。我知道如何为一个海湾站做到这一点:

test<-mean(sample(DIN1998$DIN[DIN1998$BayStation=="60081"], 
                  3, replace = FALSE, prob = NULL))

但我想知道如何为包含数百个站点的整个数据框执行此操作。谁能告诉我该怎么做?或者给个大提示?可以肯定地说,我的 R 技能非常基础 - 在此先感谢!

【问题讨论】:

    标签: r loops subset random-sample


    【解决方案1】:

    如果你想使用plyr

    ddply(DIN1998, .(BayStation), 
          summarise, 
          sample.mean=mean(sample(DIN, 3, replace=FALSE, prob=NULL)))
    

    set.seed(1) 你会得到

      BayStation sample.mean
    1      60069  0.00900000
    2      60081  0.0166666
    

    【讨论】:

      【解决方案2】:

      这是一种方法

      > set.seed(1)
      > sapply(split(DIN1998$DIN, DIN1998$BayStation), function(x){
          mean(sample(x, 3))
        })
           60069      60081 
      0.00900000 0.01666667 
      

      如果您的data.frame 太大,那么您可能需要使用data.table

      > library(data.table)
      > dt <- data.table(DIN1998)
      > set.seed(1)
      > dt[,list(Mean=mean(sample(DIN, 3))), by="BayStation"]
         BayStation       Mean
      1:      60069 0.00900000
      2:      60081 0.01666667
      

      另一种 R 基础解决方案

      > set.seed(1)
      > cbind(Mean.by.BayStation=with(DIN1998, 
                                      by(DIN, BayStation, function(x)  
                                        mean(sample(x, 3)))))
            Mean.by.BayStation
      60069         0.00900000
      60081         0.01666667
      

      【讨论】:

        【解决方案3】:

        你可以使用tapply:

        with(DIN1998, tapply(DIN, BayStation, function(x) mean(sample(x), 3)))
        #  60069  60081 
        # 0.0095 0.0140 
        

        aggregate:

        aggregate(DIN ~ BayStation, DIN1998, function(x) mean(sample(x), 3))
        #   BayStation    DIN
        # 1      60069 0.0095
        # 2      60081 0.0140
        

        【讨论】:

          猜你喜欢
          • 2012-08-09
          • 2019-10-02
          • 1970-01-01
          • 1970-01-01
          • 2012-08-21
          • 2018-06-18
          • 1970-01-01
          • 2018-09-19
          • 1970-01-01
          相关资源
          最近更新 更多