【问题标题】:lapply instead of for loop for randomised hypothesis testing rlapply 而不是 for 循环用于随机假设检验 r
【发布时间】:2020-10-09 21:30:42
【问题描述】:

我有一个看起来像这样的 df:

set.seed(42)
ID <- sample(1:30, 100, rep=T) 
Trait <- sample(0:1, 100, rep=T) 
Year <- sample(1992:1999, 100, rep=T)
df <- cbind(ID, Trait, Year)
df <- as.data.frame(df)

其中 ID 是个体有机体,特征是表型的存在/不存在,年份是进行观察的年份。

如果特征在个体之间是随机的,我想建模,像这样

library(MCMCglmm) 
m <- MCMCglmm(Trait ~ ID, random = ~ Year, data = df, family = "categorical")

现在,想打乱 Trait 列并运行 x 排列,以检查我观察到的均值和 CI 是否超出随机预期。 我可以使用 for 循环来做到这一点,但我宁愿使用 tidyverse 解决方案。 我已经读过 lapply 是一个更好的(?)替代方案,但我正在努力寻找一个足够具体的演练,我可以遵循。

我会很感激这里提供的任何建议。

干杯!

杰米

【问题讨论】:

  • lapply 是基础 R。如果你真的想要 tidyverse,请查看 purrr::map
  • 你所说的“洗牌”Trait是什么意思?
  • 随机播放,如随机播放特征列中的行而不替换。

标签: r tidyverse mcmc


【解决方案1】:

编辑于 10 月 10 日。 清理了代码,并在下面的每个评论中添加了代码,以给你一个井井有条的tibble\dataframe

### decide how many shuffles you want and name them
### in an orderly fashion for the output

shuffles <- 1:10
names(shuffles) <- paste0("shuffle_", shuffles)

library(MCMCglmm)
library(dplyr)
library(tibble)
library(purrr)

ddd <- purrr::map(shuffles,
                  ~ df %>%
                     mutate(Trait = sample(Trait)) %>%
                     MCMCglmm(fixed = Trait ~ ID,
                              random = ~ Year,
                              data = .,
                              family = "categorical",
                              verbose = FALSE)) %>%
   purrr::map( ~ tibble::as_tibble(summary(.x)$solutions, rownames = "model_term")) %>%
   dplyr::bind_rows(., .id = 'shuffle')
ddd
#> # A tibble: 20 x 7
#>    shuffle    model_term  post.mean `l-95% CI` `u-95% CI` eff.samp pMCMC
#>    <chr>      <chr>           <dbl>      <dbl>      <dbl>    <dbl> <dbl>
#>  1 shuffle_1  (Intercept)  112.         6.39     233.       103.   0.016
#>  2 shuffle_1  ID            -6.31     -13.5       -0.297    112.   0.014
#>  3 shuffle_2  (Intercept)   24.9      -72.5      133.       778.   0.526
#>  4 shuffle_2  ID            -0.327     -6.33       5.33     849.   0.858
#>  5 shuffle_3  (Intercept)    4.39     -77.3       87.4      161.   0.876
#>  6 shuffle_3  ID             1.04      -3.84       5.99     121.   0.662
#>  7 shuffle_4  (Intercept)    7.71     -79.0      107.       418.   0.902
#>  8 shuffle_4  ID             0.899     -4.40       6.57     408.   0.694
#>  9 shuffle_5  (Intercept)   30.4      -62.4      144.       732.   0.51 
#> 10 shuffle_5  ID            -0.644     -6.61       4.94     970.   0.866
#> 11 shuffle_6  (Intercept)  -45.5     -148.        42.7      208.   0.302
#> 12 shuffle_6  ID             4.73      -0.211     11.6       89.1  0.058
#> 13 shuffle_7  (Intercept)  -16.2     -133.        85.9      108.   0.696
#> 14 shuffle_7  ID             2.47      -2.42      10.3       47.8  0.304
#> 15 shuffle_8  (Intercept)    0.568      0.549      0.581      6.60 0.001
#> 16 shuffle_8  ID            -0.0185    -0.0197    -0.0168     2.96 0.001
#> 17 shuffle_9  (Intercept)   -6.95    -112.        92.2      452.   0.886
#> 18 shuffle_9  ID             2.07      -3.30       8.95     370.   0.476
#> 19 shuffle_10 (Intercept)   43.8      -57.0      159.       775.   0.396
#> 20 shuffle_10 ID            -1.36      -7.44       5.08     901.   0.62

您的原始数据

set.seed(42)
ID <- sample(1:30, 100, rep=T) 
Trait <- sample(0:1, 100, rep=T) 
Year <- sample(1992:1999, 100, rep=T)
df <- cbind(ID, Trait, Year)
df <- as.data.frame(df)

【讨论】:

  • 谢谢,这看起来很有帮助。我假设大括号不会覆盖我观察到的数据?此外,这本质上是否与 Is 在 for 循环中做的事情相同(使用特征 col 随机化行)?我不熟悉咕噜声
  • 原始数据框本身保持不变。是的,您可以在 for 循环中完成所有这些操作。
  • 作为另一个问题,因为我不习惯从摘要输出中提取那么多数据(用于多次迭代),有没有一种简单的方法可以在单个 df 中使用它?我猜想在一个可以集成的循环中 - 像这样stackoverflow.com/questions/43796143/…
  • 我即将发布对清理答案的编辑并为您提供更好的输出
  • 有没有办法在这个函数的输出中添加固定和随机变量(而不是仅仅固定)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 2021-10-12
  • 2017-07-12
相关资源
最近更新 更多