【发布时间】:2020-05-04 09:21:56
【问题描述】:
正确的:这是我在向 CRAN 提交 R 包时遇到的问题。所以我
- 无法控制堆栈大小(因为问题发生在某个 CRAN 平台上)
- 我无法提供可重现的示例(因为我不知道 CRAN 上的确切配置)
问题
当尝试将cSEM.DGP package 提交给 CRAN 时,自动预测试(适用于 Debian x86_64-pc-linux-gnu;不适用于 Windows!)失败并出现注释:C stack usage 7975520 is too close to the limit。
我知道这是由一个具有三个参数的函数引起的,该函数的主体大约有 800 行长。函数体由这些参数的加法和乘法组成。它是函数 varzeta6(),您可以找到 here(从第 647 行开始)。
我该如何解决这个问题?
我不能做的事情:
- 提供一个可重现的例子(至少我不知道怎么做)
- 更改堆栈大小
我在想的事情:
- 尝试将函数分解为更小的部分。但我不知道如何最好地做到这一点。
- 以某种方式预编译?功能(老实说,我只是猜测)所以 CRAN 不会抱怨?
让我知道你的想法!
细节/背景
varzeta6()(以及varzeta4()/varzeta5() 甚至更多varzeta7())如此长且 R 效率低的原因是它们本质上是从mathematica 复制粘贴的(在将mathematica 代码简化为尽可能好并将其调整为有效的 R 代码)。因此,代码绝不是 R 优化的(@MauritsEvers 正确地指出了这一点)。
为什么我们需要mathematica?因为我们需要的是递归结构方程模型的模型隐含构造相关矩阵的一般形式,该模型具有多达 8 个构造作为模型方程参数的函数。此外还有约束。 为了了解这个问题,让我们采用一个可以递归求解的两个方程组:
- Y2 = beta1*Y1 + zeta1
- Y3 = beta2*Y1 + beta3*Y2 + zeta2
我们感兴趣的是协方差:E(Y1*Y2)、E(Y1*Y3) 和 E(Y2*Y3) 作为 beta1、beta2、beta3 的函数,在
- E(Y1) = E(Y2) = E(Y3) = 0,
- E(Y1^2) = E(Y2^2) = E(Y3^3) = 1
- E(Yi*zeta_j) = 0(其中 i = 1、2、3 和 j = 1、2)
对于这样一个简单的模型,这是相当微不足道的:
- E(Y1*Y2) = E(Y1*(beta1*Y1 + zeta1) = beta1*E(Y1^2) + E(Y1*zeta1) = beta1
- E(Y1*Y3) = E(Y1*(beta2*Y1 + beta3*(beta1*Y1 + zeta1) + zeta2) = beta2 + beta3*beta1
- E(Y2*Y3) = ...
但是,当您添加 Y4、Y5 直到 Y8 时,您会发现这很快就会变得混乱。
一般来说,模型隐含的构造相关矩阵可以写成(表达式实际上看起来更复杂,因为我们还允许多达 5 个外生构造。这就是为什么varzeta1() 已经看起来很复杂。但现在忽略这个。) :
- V(Y) = (I - B)^-1 V(zeta)(I - B)'^-1
其中 I 是单位矩阵,B 是模型参数(β)的下三角矩阵。 V(zeta) 是对角矩阵。函数varzeta1()、varzeta2()、...、varzeta7() 计算主对角线元素。由于我们将 Var(Yi) 限制为始终为 1,因此 zeta 的方差随之而来。以方程 Var(Y2) = beta1^2*Var(Y1) + Var(zeta1) --> Var(zeta1) = 1 - beta1^2 为例。这在这里看起来很简单,但是当我们取这样一个递归方程链中的第 6 个方程的方差时,它变得极其复杂,因为 Var(zeta6) 取决于所有先前的 Y1、...、Y5 之间的协方差,它们本身就是取决于它们各自先前的协方差。
好吧,我不知道这是否能让事情变得更清楚。以下是重点:
-
varzeta1(), ...,varzeta7()的代码是从 Mathematica 复制粘贴的,因此未经过 R 优化。 - Mathematica 是必需的,因为据我所知,R 无法处理符号计算。
- 我可以“手动”进行 R 优化(这非常乏味)
- 我认为
varzetaX()的结构必须是给定的。因此,问题是:我可以以某种方式使用这个功能吗?
【问题讨论】:
-
你跑
R CMD check --as-cran cSEM.DGP了吗?选项--as-cran旨在解决这些问题。 -
另外,
varzeta6非常可怕。它计算的公式一定是从某个地方来的,代码不能简化吗? -
不幸的是它不能。代码实际上是从 Mathematica 复制粘贴的,我们在其中运行生成 varzeta6 作为输出的计算。我们使用 Mathematica 来简化代码。如果没有简化,varzeta6 的主体会更长:-)
-
我确实运行了
R CMD check --as-cran cSEM.DGP(在 Rstudio 中)。我的机器上没有问题(我有 Windows)。该问题仅出现在 CRAN debian x86_64-pc-linux-gnu -
这个过程什么时候发生?也许你可以发送日志?我之前遇到的示例没有在 CRAN 服务器上运行或花费太长时间,在这种情况下,您可以使用
\dontrun{}排除示例。对于可以排除某些测试在 CRAN 服务器上运行的测试也是如此。
标签: r package cran submission