Search code examples
rloopsnestedsample

Sampling Nested For Loop


My loop knowledge is very minimal but I currently have a loop written, which takes values from three vectors (small.dens, med.dens, and large.dens) and each vector has 17 values. I have the loop setup to randomly select 2 values, then 3, then 4... all the way up to 17. Using these values, it calculates the mean and standard error (using the plotrix package). It then places these calculated means and standard errors into new vectors (small.density, small.stanerr, medium.density, medium.stanerr, large.density, and large.stanerr). Next, separately from the loop, I combine these vectors into a dataframe.

library(plotrix)

small.density = rep(NA,16)
small.stanerr = rep(NA,16)
medium.density = rep(NA,16)
medium.stanerr = rep(NA,16)
large.density = rep(NA,16)
large.stanerr = rep(NA,16)

for(i in 2:17){
  xx=sample(small.dens,i,replace=TRUE)
  small.density[[i]] = mean(xx)
  small.stanerr[[i]] = std.error(xx)
  yy = sample(med.dens, i, replace=TRUE)
  medium.density[[i]] = mean(yy)
  medium.stanerr[[i]] = std.error(yy)
  zz = sample(large.dens, i, replace=TRUE)
  large.density[[i]] = mean(zz)
  large.stanerr[[i]] = std.error(zz)
}

I then want to run this loop 100 times, ultimately taking the mean, if that makes sense. For example, I would like it to select 2,3,4...17 values 100 times, taking the mean and standard error each time, and then taking the mean of all 100 times. Does this make sense? Would I make another for loop, turning this into a nested loop? How would I go about doing this? Thanks!


Solution

  • There are other ways to achieve what you want, but if you do not want to change your code, then just wrap it in something like this

    res <- do.call(rbind, lapply(1:100, function(x) {
      within(data.frame(
        n = x, 
        size = 2:17, 
        small.density = rep(NA,16), 
        small.stanerr = rep(NA,16), 
        medium.density = rep(NA,16), 
        medium.stanerr = rep(NA,16), 
        large.density = rep(NA,16), 
        large.stanerr = rep(NA,16)
      ), {
        for(i in 2:17){
          xx = sample(small.dens,i,replace=TRUE)
          small.density[[i - 1L]] = mean(xx)
          small.stanerr[[i - 1L]] = std.error(xx)
          yy = sample(med.dens, i, replace=TRUE)
          medium.density[[i - 1L]] = mean(yy)
          medium.stanerr[[i - 1L]] = std.error(yy)
          zz = sample(large.dens, i, replace=TRUE)
          large.density[[i - 1L]] = mean(zz)
          large.stanerr[[i - 1L]] = std.error(zz)
        }
        rm(xx, yy, zz, i)
      })
    }))
    

    res looks like this

    > head(res, 20)
       n size small.density small.stanerr medium.density medium.stanerr large.density large.stanerr
    1  1    2   -0.04716195    0.35754422     13.1014925       4.374055    -42.089591      30.87786
    2  1    3   -0.15893367    0.34557922     -0.2680632       6.206081     52.984076      36.85058
    3  1    4    0.10013995    0.62374467     -0.1944930       5.784211   -112.684774      30.50707
    4  1    5    0.40654132    0.40815013      1.6096970       5.026714     45.810098      46.58469
    5  1    6    0.13310242    0.32104512     -6.9989844       4.232091    -22.312165      48.14705
    6  1    7    0.21283027    0.53633472     -5.0702365       3.829677    -43.266482      41.74286
    7  1    8    0.13870439    0.27161346      4.1629469       3.214053     -9.045643      48.49930
    8  1    9    0.06495734    0.36738163      3.9742069       3.540913    -43.954345      38.23816
    9  1   10   -0.01882762    0.37570468     -3.1764203       3.740403    -43.156792      38.47531
    10 1   11   -0.02115580    0.26239465     -2.2026077       2.702412      7.343837      30.58314
    11 1   12    0.09967753    0.27360125      3.9603382       3.214921    -13.461632      29.39910
    12 1   13    0.53121414    0.27561862      4.3593802       1.872685    -38.572491      25.37029
    13 1   14    0.21547909    0.36345292     -0.3377787       2.732968     17.305232      26.08317
    14 1   15    0.33957964    0.23029520      0.4832063       2.886160      8.145410      18.23901
    15 1   16    0.26871985    0.26846012     -6.7634873       3.436742     -4.011269      20.33814
    16 1   17    0.24927792    0.20534048     -0.7481315       1.899348      9.993280      24.49623
    17 2    2   -1.10840346    0.07123407     -3.4317644       6.966096    -30.384945     121.00972
    18 2    3    1.73947551    0.35986535     -2.1415966       5.628115    -57.857871      10.47413
    19 2    4    0.40033834    0.41963615     -4.2156733       1.206414     27.891021      13.84453
    20 2    5   -0.08704736    0.52872770      0.3137693       2.974888     -3.100414      57.89126
    

    If you want to calculate the mean of the 100 simulated values for each size, then just

    aggregate(. ~ size, res[-1L], mean)
    

    which gives you

       size small.density small.stanerr medium.density medium.stanerr large.density large.stanerr
    1     2    0.02872578     0.6341294      1.0938287       5.518797      3.141204      53.20675
    2     3    0.16985732     0.5388110     -0.1627867       5.185643     -6.660756      49.83607
    3     4    0.20543404     0.4815581      0.1385016       4.519419     -8.093673      46.64984
    4     5    0.13019280     0.4546794      0.1299331       4.166335    -10.300542      41.40444
    5     6    0.10675158     0.4307113      0.2191516       4.033863    -12.068151      38.95312
    6     7    0.19326831     0.3834507      0.8784275       3.513812     -6.920378      36.17856
    7     8    0.09020638     0.3580780      0.4388388       3.443349     -5.335405      30.49615
    8     9    0.13956838     0.3558005      0.3740251       3.313501    -15.290834      31.64833
    9    10    0.18368962     0.3397191      0.4600761       3.051425     -5.505220      29.46165
    10   11    0.20653866     0.3116104      0.9913534       2.804659     -8.809398      28.79097
    11   12    0.14653661     0.2988422      0.3337274       2.624418     -5.128882      26.78074
    12   13    0.12255652     0.2864998      0.2085829       2.719396    -11.548064      27.08497
    13   14    0.13102809     0.2830709      0.6448798       2.586491     -4.676053      25.21800
    14   15    0.14536840     0.2749606      0.3415879       2.522826    -11.968496      24.44427
    15   16    0.14871831     0.2571571      0.2218365       2.463486    -10.335511      23.64304
    16   17    0.13664397     0.2461108      0.3387764       2.348594     -9.969407      22.84736