在不使用 R 中的 for 循环的情况下在每次迭代时模拟不同数量的观察

Simulating different number of observations at each iteration without using for loop in R

我想在 R 中针对不同的 df1 和 df2 模拟 F 分布。这是带输出的 MWE。

library(plyr)
set.seed(12345)
mdply(n = 4, expand.grid(df1=1:2, df2=1:3), rf, ncp=0)

   df1 df2         V1           V2          V3           V4
1   1   1  0.1347567 8.500762e-06  0.72264208 4518.4539675
2   2   1  0.2530428 1.486142e+00 72.21221004  141.6067825
3   1   2  1.5186844 9.277733e-02  0.64339217    0.7640852
4   2   2 25.3820751 1.157754e-01  0.73888229    0.3737995
5   1   3  6.1314292 7.929352e-01  0.04016619    0.3938349
6   2   3  0.5724190 1.056585e+01  0.88576080    1.1905973

我还需要不同数量的模拟。我想知道如何在不使用 for 循环的情况下实现这一目标。

mdply(expand.grid(n=4:5, df1=1:2, df2=1:3), rf, ncp=0)

Error in list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor) : 
  Results do not have equal lengths

这是一种方法:

pars <- expand.grid(n = 4, df1 = 1:2, df2 = 1:3, ncp = 0)
set.seed(12345)
do.call("mapply", c(FUN = rf, as.list(pars), SIMPLIFY = TRUE))

这给出了

> do.call("mapply", c(FUN = rf, as.list(pars), SIMPLIFY = TRUE))
             [,1]        [,2]       [,3]       [,4]       [,5]       [,6]
[1,] 1.347567e-01   0.2530428 1.51868436 25.3820751 6.13142922  0.5724190
[2,] 8.500762e-06   1.4861425 0.09277733  0.1157754 0.79293521 10.5658537
[3,] 7.226421e-01  72.2122100 0.64339217  0.7388823 0.04016619  0.8857608
[4,] 4.518454e+03 141.6067825 0.76408522  0.3737995 0.39383494  1.1905973

对于变化的n,只需扩展原始参数:

pars <- expand.grid(n = 4:5, df1 = 1:2, df2 = 1:3, ncp = 0)
set.seed(12345)
do.call("mapply", c(FUN = rf, as.list(pars)))

给出:

> do.call("mapply", c(FUN = rf, as.list(pars)))
[[1]]
[1] 1.347567e-01 8.500762e-06 7.226421e-01 4.518454e+03

[[2]]
[1]  1.86524680 20.26270285  0.26845681  0.06860617  0.32628251

[[3]]
[1] 91.0530148  0.1471053  3.3674264  5.6419166

[[4]]
[1] 11.3468626  0.7450701 32.9943342  1.8116354  0.7173261

[[5]]
[1] 0.3686938 1.2020445 6.8348659 0.2035982

[[6]]
[1] 14.88249844  0.26743564  0.36008560  0.06546096  1.87464074

....

您可以在单个 n 情况下附加参数:

pars <- expand.grid(n = 4, df1 = 1:2, df2 = 1:3, ncp = 0)
set.seed(12345)
rands <- do.call("mapply", c(FUN = rf, as.list(pars), SIMPLIFY = TRUE))
cbind(pars, t(rands)) ## transpose `rands`

给出:

> cbind(pars, t(rands)) ## transpose `rands`
  n df1 df2 ncp          1            2           3            4
1 4   1   1   0  0.1347567 8.500762e-06  0.72264208 4518.4539675
2 4   2   1   0  0.2530428 1.486142e+00 72.21221004  141.6067825
3 4   1   2   0  1.5186844 9.277733e-02  0.64339217    0.7640852
4 4   2   2   0 25.3820751 1.157754e-01  0.73888229    0.3737995
5 4   1   3   0  6.1314292 7.929352e-01  0.04016619    0.3938349
6 4   2   3   0  0.5724190 1.056585e+01  0.88576080    1.1905973

您将无法使用 n = 4:5 版本轻松完成此操作,因为您需要填写。鉴于您已加载 plyr,请使用它的 rbind.fill() 函数:

pars <- expand.grid(n = 4:5, df1 = 1:2, df2 = 1:3, ncp = 0)
set.seed(12345)
do.call("mapply", c(FUN = rf, as.list(pars)))
rands <- do.call("mapply", c(FUN = rf, as.list(pars)))
randsdf <- lapply(rands, function(x) as.data.frame(t(x)))
rbind.fill(randsdf)

这给出了

> rbind.fill(randsdf)
           V1           V2           V3           V4          V5
1   0.3684304 186.73376725 3.039183e-01 1.406014e-01          NA
2   0.7545174   0.91995520 1.079430e+03 1.817998e+03  7.47710289
3   7.0747278   8.20808462 3.322224e-01 3.007743e+00          NA
4   1.9073559   4.13709509 8.722492e-01 2.089466e+00  0.81639181
5   0.3710252   0.85090566 4.398314e-01 2.546412e+00          NA
6   3.0373048   1.19982549 1.971773e-02 4.597047e-01  0.02247717
7   0.1659259   2.48738654 2.214283e+01 1.574352e+00          NA
8   3.6552135   4.08015469 1.339006e+01 1.199039e+00  0.61507504
9   0.1473347   0.01749103 5.285231e-02 6.472382e-01          NA
10  0.1102851   0.26849717 4.911630e-01 6.862164e-02  0.00373183
11 30.9371115   1.66420909 1.049709e+00 9.076381e-01          NA
12  0.2798656   0.39701996 5.146740e-02 6.545098e+00 25.91742143

结合cbind这一步我们得到了

cbind(pars, rbind.fill(randsdf))

> cbind(pars, rbind.fill(randsdf))
   n df1 df2 ncp         V1           V2           V3           V4          V5
1  4   1   1   0  0.3684304 186.73376725 3.039183e-01 1.406014e-01          NA
2  5   1   1   0  0.7545174   0.91995520 1.079430e+03 1.817998e+03  7.47710289
3  4   2   1   0  7.0747278   8.20808462 3.322224e-01 3.007743e+00          NA
4  5   2   1   0  1.9073559   4.13709509 8.722492e-01 2.089466e+00  0.81639181
5  4   1   2   0  0.3710252   0.85090566 4.398314e-01 2.546412e+00          NA
6  5   1   2   0  3.0373048   1.19982549 1.971773e-02 4.597047e-01  0.02247717
7  4   2   2   0  0.1659259   2.48738654 2.214283e+01 1.574352e+00          NA
8  5   2   2   0  3.6552135   4.08015469 1.339006e+01 1.199039e+00  0.61507504
9  4   1   3   0  0.1473347   0.01749103 5.285231e-02 6.472382e-01          NA
10 5   1   3   0  0.1102851   0.26849717 4.911630e-01 6.862164e-02  0.00373183
11 4   2   3   0 30.9371115   1.66420909 1.049709e+00 9.076381e-01          NA
12 5   2   3   0  0.2798656   0.39701996 5.146740e-02 6.545098e+00 25.91742143
mlply(expand.grid(n=4:5, df1=1:2, df2=1:3), rf, ncp=0)

给你一个列表。您可以将其与 rbind.fill 结合使用,如 Gavin 的回答。