如何从多个数据子集中为随机样本编写循环?

时间:2014-01-08 20:22:25

标签: r loops subset random-sample

我有一个(可能是简单的)问题,我无法弄明白。

我想编写一个循环(或使用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技能非常基础 - 提前谢谢!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可以使用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

答案 2 :(得分:0)

这是一种方法

> 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 Base解决方案

> 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