如何在 R 中为蒙特卡洛创建更高效​​的模拟循环

2024-01-09

此练习的目的是创建营养摄入值的人群分布。早期数据中有重复的测量值,这些测量值已被删除,因此每一行都是数据框中唯一的人。

我有这段代码,在使用少量数据框行进行测试时效果非常好。对于所有 7135 行,速度非常慢。我试图给它计时,但当我的机器上的运行时间达到 15 小时时,我就崩溃了。这system.time结果是Timing stopped at: 55625.08 2985.39 58673.87.

我将不胜感激任何有关加快模拟速度的评论:

Male.MC <-c()
for (j in 1:100)            {
for (i in 1:nrow(Male.Distrib))  {
    u2        <- Male.Distrib$stddev_u2[i] * rnorm(1, mean = 0, sd = 1)
    mc_bca    <- Male.Distrib$FixedEff[i] + u2
    temp      <- Lambda.Value*mc_bca+1
    ginv_a    <- temp^(1/Lambda.Value)
    d2ginv_a  <- max(0,(1-Lambda.Value)*temp^(1/Lambda.Value-2))
    mc_amount <- ginv_a + d2ginv_a * Male.Resid.Var / 2
z <- data.frame(
     RespondentID = Male.Distrib$RespondentID[i], 
     Subgroup     = Male.Distrib$Subgroup[i], 
     mc_amount    = mc_amount,
     IndvWeight   = Male.Distrib$INDWTS[i]/100
     )

Male.MC <- as.data.frame(rbind(Male.MC,z))
    }
}

对于我的数据集中的 7135 个观测值中的每一个,创建 100 个模拟营养值,然后转换回原始测量水平(模拟使用 BoxCox 转换营养值的非线性混合效应模型的结果)。

我不想使用for循环,正如我读到的那样,它们效率低下R但我对基于的选项了解不够apply使用它们作为替代方案。R如果在独立计算机上运行,​​通常这将是运行 Windows 7 变体的标准戴尔型台式机,如果这会影响如何更改代码的建议。

更新:要重现此内容以进行测试,Lambda.Value=0.4 且Male.Resid.Var=12.1029420429778 和Male.Distrib$stddev_u2是所有观测值的常数值。

str(Male.Distrib) is

'data.frame':   7135 obs. of  14 variables:
 $ RndmEff     : num  1.34 -5.86 -3.65 2.7 3.53 ...
 $ RespondentID: num  9966 9967 9970 9972 9974 ...
 $ Subgroup    : Ord.factor w/ 6 levels "3"<"4"<"5"<"6"<..: 4 3 2 4 1 4 2 5 1 2 ...
 $ RespondentID: int  9966 9967 9970 9972 9974 9976 9978 9979 9982 9993 ...
 $ Replicates  : num  41067 2322 17434 21723 375 ...
 $ IntakeAmt   : num  33.45 2.53 9.58 43.34 55.66 ...
 $ RACE        : int  2 3 2 2 3 2 2 2 2 1 ...
 $ INDWTS      : num  41067 2322 17434 21723 375 ...
 $ TOTWTS      : num  1.21e+08 1.21e+08 1.21e+08 1.21e+08 1.21e+08 ...
 $ GRPWTS      : num  41657878 22715139 10520535 41657878 10791729 ...
 $ NUMSUBJECTS : int  1466 1100 1424 1466 1061 1466 1424 1252 1061 1424 ...
 $ TOTSUBJECTS : int  7135 7135 7135 7135 7135 7135 7135 7135 7135 7135 ...
 $ FixedEff    : num  6.09 6.76 7.08 6.09 6.18 ...
 $ stddev_u2   : num  2.65 2.65 2.65 2.65 2.65 ...

head(Male.Distrib) is

    RndmEff RespondentID Subgroup RespondentID Replicates IntakeAmt RACE INDWTS    TOTWTS   GRPWTS NUMSUBJECTS TOTSUBJECTS  FixedEff stddev_u2
1  1.343753         9966        6         9966      41067 33.449808    2  41067 120622201 41657878        1466        7135  6.089918  2.645938
2 -5.856516         9967        5         9967       2322  2.533528    3   2322 120622201 22715139        1100        7135  6.755664  2.645938
3 -3.648339         9970        4         9970      17434  9.575439    2  17434 120622201 10520535        1424        7135  7.079757  2.645938
4  2.697533         9972        6         9972      21723 43.340180    2  21723 120622201 41657878        1466        7135  6.089918  2.645938
5  3.531878         9974        3         9974        375 55.660607    3    375 120622201 10791729        1061        7135  6.176319  2.645938
6  6.627767         9976        6         9976      48889 91.480049    2  48889 120622201 41657878        1466        7135  6.089918  2.645938

更新 2:导致该问题的函数行NaN结果是

d2ginv_a  <- max(0,(1-Lambda.Value)*temp^(1/Lambda.Value-2))

感谢大家的帮助和评论,以及回复的速度。

更新:@Ben Bolker 是正确的,这是负面的temp导致 NaN 问题的值。我通过一些测试错过了这一点(在注释掉该函数之后,这样只有temp返回值,并调用我的结果数据框Test)。这段代码重现了NaN issue:

> min(Test)
[1] -2.103819
> min(Test)^(1/Lambda.Value)
[1] NaN

但是将值作为值输入,然后运行相同的(?)计算会给我一个结果,所以我在进行手动计算时错过了这一点:

> -2.103819^(1/Lambda.Value) 
[1] -6.419792

我现在有工作代码(我认为)使用矢量化,而且速度快得令人眼花缭乱。为了防止其他人遇到这个问题,我在下面发布了工作代码。我必须添加最小值以防止计算出现 rnorm结果到数据帧,这确实减慢了速度,以这种方式创建它们然后使用cbind真的很快。Male.Distrib是我的 7135 个观测值的完整数据框,但此代码应该适用于我之前发布的缩减版本(未经测试)。

Min_bca <- ((.5*min(Male.AddSugar$IntakeAmt))^Lambda.Value-1)/Lambda.Value
Test <- Male.Distrib[rep(seq.int(1,nrow(Male.Distrib)), 100), 1:ncol(Male.Distrib)]
RnormOutput <- rnorm(nrow(Test),0,1)
Male.Final <- cbind(Test,RnormOutput)
Male.Final$mc_bca    <- Male.Final$FixedEff + (Male.Final$stddev_u2 *     Male.Final$RnormOutput)
Male.Final$temp      <- ifelse(Lambda.Value*Male.Final$mc_bca+1 > Lambda.Value*Min_bca+1,
                           Lambda.Value*Male.Final$mc_bca+1, Lambda.Value*Min_bca+1)
Male.Final$ginv_a    <- Male.Final$temp^(1/Lambda.Value)
Male.Final$d2ginv_a  <- ifelse(0 > (1-Lambda.Value)*Male.Final$temp^(1/Lambda.Value-2),
                           0, (1-Lambda.Value)*Male.Final$temp^(1/Lambda.Value-2))
Male.Final$mc_amount <- Male.Final$ginv_a + Male.Final$d2ginv_a * Male.Resid.Var / 2

当日课程:

  • 如果您尝试执行我之前尝试的操作,则分布函数似乎不会在循环中重新采样
  • 你不能使用max()我尝试的方式,因为它返回列中的最大值,而我想要两个值中的最大值。这ifelse声明是替换之一要做的。

这是解决两个最大速度问题的方法:

  1. 而不是循环观察(i),我们一次性计算它们。
  2. 而不是循环 MC 复制(j), 我们用replicate,这是一个简化的apply就是为了这个目的。

首先,我们加载数据集并为您正在做的事情定义一个函数。

Male.Distrib = read.table('MaleDistrib.txt', check.names=F)

getMC <- function(df, Lambda.Value=0.4, Male.Resid.Var=12.1029420429778) {
  u2        <- df$stddev_u2 * rnorm(nrow(df), mean = 0, sd = 1)
  mc_bca    <- df$FixedEff + u2
  temp      <- Lambda.Value*mc_bca+1
  ginv_a    <- temp^(1/Lambda.Value)
  d2ginv_a  <- max(0,(1-Lambda.Value)*temp^(1/Lambda.Value-2))
  mc_amount <- ginv_a + d2ginv_a * Male.Resid.Var / 2
  mc_amount
}

然后我们复制它很多次。

> replicate(10, getMC(Male.Distrib))
         [,1]      [,2]     [,3]     [,4]      [,5]     [,6]     [,7]     [,8]     [,9]    [,10]
[1,] 36.72374 44.491777 55.19637 23.53442 23.260609 49.56022 31.90657 25.26383 25.31197 20.58857
[2,] 29.56115 18.593496 57.84550 22.01581 22.906528 22.15470 29.38923 51.38825 13.45865 21.47531
[3,] 61.27075 10.140378 75.64172 28.10286  9.652907 49.25729 23.82104 31.77349 16.24840 78.02267
[4,] 49.42798 22.326136 33.87446 14.00084 25.107143 25.75241 30.20490 33.14770 62.86563 27.33652
[5,] 53.45546  9.673162 22.66676 38.76392 30.786100 23.42267 28.40211 35.95015 43.75506 58.83676
[6,] 34.72440 23.786004 63.57919  8.08238 12.636745 34.11844 14.88339 21.93766 44.53451 51.12331

然后你可以重新格式化,添加ID等,但这是主要计算部分的想法。祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 R 中为蒙特卡洛创建更高效​​的模拟循环 的相关文章

  • 无法编译包“maps”

    当我安装 maps 包时 安装中出现警告 ld warning ignoring file Library Developer CommandLineTools SDKs MacOSX10 14 sdk usr lib libSystem
  • 条件和分组 mutate dplyr

    假设我有以下每个抽屉库存增加的数据 gt socks year drawer nbr sock total 1990 1 2 1991 1 2 1990 2 3 1991 2 4 1990 3 2 1991 3 1 我想要一个二进制变量来标
  • 在闪亮的数据表中为每个单元格显示工具提示或弹出窗口?

    有没有什么方法可以为 r闪亮数据表中的每个单元格获取工具提示 有很多方法可以获取悬停行或列 但我找不到一种方法来获取行和列索引并为每个单元格显示不同的悬停工具提示 任何人都可以修改以下代码吗 library shiny library DT
  • 安装 2.15 后 ggplot2 中的 alpha 通道不起作用

    更新到 R 2 15 后 ggplot 中的 alpha 通道似乎不再起作用 plot rnorm 100 rnorm 100 bg cc000055 pch 21 工作得很好但是 qplot rnorm 100 rnorm 100 col
  • 更改ggplot2中的字体

    曾几何时 我改变了我的ggplot2字体使用windowsFonts Times windowsFont TT Times New Roman 现在 我无法摆脱这一切 在尝试设置family in ggplot2 theme 当我用不同的字
  • 如何优化分割重叠范围?

    我编写的这个 Python 脚本用于将重叠范围拆分为唯一范围 最后一次迭代 https codereview stackexchange com questions 285932 python script to split overlap
  • 如何使用 dplyr 管道将额外参数传递给 purrr::map

    我有以下数据框和功能 param df lt data frame x 1 3 0 1 y 3 1 0 2 param df gt x y gt 1 1 1 2 8 gt 2 2 1 1 8 gt 3 3 1 0 8 my function
  • 在什么情况下 do-while 比 while 更高效?

    while 与 do while while 和 do while 在功能上是等效的当块为空时 虽然 while 看起来更自然 do while keepLooping while keepLooping 使用空块的 while do wh
  • 计算字符串向量中连续数字的函数

    我想创建一个函数 它接受至少 1 个元素的字符串对象并包含数字 2 到 5 并确定是否存在至少 N 长度的连续数字 其中 N 是实际数字值 如果是 则返回字符串 true 否则返回字符串 false 例如 Input 555123 Outp
  • 如何在 foreach( ... , .packages="pkg") %dopar% 中指定 R 包的位置

    我的 包 安装在其他地方 我如何告诉 foreach 在哪里可以找到该包 foreach i 1 2 packages pkg dopar 这给我错误消息 worker initialization failed there is no p
  • 使用操作按钮在闪亮的 R 中添加包含现有数据框的新行

    我正在构建一个闪亮的表单 它将从 textInput 字段获取数据 并将这些输入与文本文件 将通过文件输入上传 组合起来 并在主面板中显示输出 有一个操作按钮用于第一次更新数据 从文本输入中获取数据并与处理后的文本文件合并 我添加了另一个操
  • 如何在 R 中 fork 进程

    我试图了解 R 多核包实现的分叉系统 包的例子是 p lt fork if inherits p masterProcess cat I m a child Sys getpid n exit I was a child cat I m t
  • 如何使用 ggplot2 将 IPCC 点画添加到全球地图

    我需要将 IPCC style 点画添加到全球地图中 如下所示这个帖子 https stackoverflow com questions 11736996 adding stippling to image contour plot 不过
  • 我的用例可以合并到单个查询中而不影响性能吗?

    我主要着眼于改善表现查询的内容以及是否能够解决单一查询对于我的用例之一 解释如下 涉及到2张表 Table 1 EMPLOYEE column1 column2 email1 email2 column5 column6 Table 2 E
  • 在 R 中显示变量的精确值

    gt x lt 1 00042589212565 gt x 1 1 000426 如果我想打印的确切值x 我该怎么办呢 抱歉 如果这是一个愚蠢的问题 我尝试在谷歌上搜索 R 和 精确 或 圆形 但我得到的只是有关如何舍入的文章 先感谢您 所
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • Android Drawable 绘图性能?

    在我看来 我有一个简单的 ARGB 可绘制对象 大约需要 2 毫秒才能绘制 但我可以在 0 5 毫秒内绘制与位图相同的文件 只是一些快速代码 我真的不能认为它是一个选项 优化可绘制对象的绘制速度的最佳方法是什么 这取决于可绘制的数量以及每个
  • jQuery 选择器:为什么 $("#id").find("p") 比 $("#id p") 更快

    该页面的作者 http 24ways org 2011 your jquery now with less suck http 24ways org 2011 your jquery now with less suck断言 jQuery
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • IronPython 中批量求值表达式的性能

    在 C 4 0 应用程序中 我有一个具有相同长度的强类型 IList 的字典 一个基于动态强类型列的表 我希望用户根据将在所有行上聚合的可用列提供一个或多个 python 表达式 在静态上下文中它将是 IDictionary

随机推荐