在 R 中使用 glmnet 和 dotCall64 的长向量

2024-05-05

我使用 glmnet 和 glmnetcr 来拟合序数回归模型。

不幸的是,我的模型矩阵约为 640000 * 5000。这大于可以存储在 32 位整数中的大小,并且我遇到了其他人描述的相同问题:R 向量大小限制:“.C 中不支持长向量(参数 5)” https://stackoverflow.com/questions/34165654/r-vector-size-limit-long-vectors-argument-5-are-not-supported-in-c

如果我只使用一半的数据,我可以在有足够内存的本地服务器上运行它,并且不会出现任何问题。

我尝试使用 dotCall64 包来实现上面帖子中的“解决方案”。我已将 .Fortran 调用替换为 .C64,并指定了每个变量的数据类型。然而,每次运行代码时,我要么得到无意义的 lambda 值 (9.9e35),要么得到段错误,例如:

* 捕获段错误 *地址 0x1511aaeb0,导致“内存未映射”

我得到的地址和确切的地址每次都会有所不同,因此我认为我在实施此解决方案时做错了什么。

这是函数 lognet() 中迄今为止的代码(该函数最终由 glmnetcr 和 glmnet 调用,并将变量传递给 fortran 代码)

原始代码在lognet()中

.Fortran("lognet", parm = alpha, nobs, nvars, nc, as.double(x), 
        y, offset, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh, 
        isd, intr, maxit, kopt, lmu = integer(1), a0 = double(nlam * 
            nc), ca = double(nx * nlam * nc), ia = integer(nx), 
        nin = integer(nlam), nulldev = double(1), dev = double(nlam), 
        alm = double(nlam), nlp = integer(1), jerr = integer(1), 
        PACKAGE = "glmnet")

修改lognet()中的代码

.C64("lognet", SIGNATURE = c("double","int",   "int",   "int",   "int64",                         
                             "double","double","int",   "double","double"
                             "int",   "int",   "int",   "double","double",
                             "double","int",   "int",   "int",   "int",
                             "int",   "double","double","int",   "int",
                             "double","double","double","int",    "int"),
                parm = alpha, nobs, nvars, nc, as.double(x), 
                y, offset, jd, vp, cl, ne, nx, nlam, flmin, ulam, thresh, 
                isd, intr, maxit, kopt, lmu = integer(1), a0 = double(nlam * nc), ca = double(nx * nlam * nc), ia = integer(nx), 
                nin = integer(nlam), nulldev = double(1), dev = double(nlam), 
                alm = double(nlam), nlp = integer(1), jerr = integer(1), 
                PACKAGE = "glmnet")

玩具示例(数据比实际小得多)

library(glmnetcr)
library(dotCall64)

x1 <- cbind(c(0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1),c(0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,1),c(0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1),c(0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,1),c(0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1),c(0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1),c(0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1))
y1 <- c(0,0,0,1,1,1,2,2,0,1,0,1,1,2,1,2)

testA  <- glmnetcr(x=x1,y=y1,method = "forward", nlambda=10,lambda.min.ratio=0.001, alpha =1,maxit = 500,standardize=FALSE)

使用原始 lognet() 代码运行它不会产生任何问题。 使用修改后的 lognet() 代码运行它会导致奇怪的 lambda 值估计和/或段错误(似乎是随机发生的)。我的第一个猜测是我有一个变量输入错误,但我已经将所有内容检查了两次并且看不到问题。另一种选择是底层 Fortran 代码无法处理 64 位整数。我对 Fortran 的了解为零,甚至不知道如果是这种情况如何开始解决问题。


所以我联系了 glmnet 的软件包维护者。他们有转换为 .C64 的经验。在他们的帮助和一点点摆弄下,我能够让以下代码正常工作。为了运行它,我创建了一个名为 glmnet64 的新函数,它调用另一个新函数 lognet64 而不是原始的 lognet 调用。 lognet64 与原始 lognet 函数相同,但用以下内容替换了 .Fortran 调用:

.C64("lognet", SIGNATURE =   c("double", "integer","integer","integer","double",
                               "double", "double", "integer","double", "double",
                               "integer","integer","integer","double", "double",
                               "double", "integer","integer","integer","integer",
                               "integer","double", "double", "integer","integer",
                               "double", "double", "double","integer","integer"),
          parm = alpha,nobs,           nvars,            nc,      as.double(x), 
          y,           offset,         jd,                  vp,      cl, 
          ne,          nx,             nlam,                flmin,   ulam, 
          thresh,      isd,            intr,                maxit,   kopt, 
          lmu = integer(1),    a0 = double(nlam * nc), 
          ca = double(nx * nlam * nc), ia = integer(nx), nin = integer(nlam), 
          nulldev = double(1), dev = double(nlam),     alm = double(nlam),          
          nlp = integer(1), jerr = integer(1), 
          INTENT = c(rep("rw",4),"r",rep("rw",15),rep("w",10)),     
          PACKAGE = "glmnet",
          NAOK = TRUE)

关键似乎是正确指定所有变量类型。能够在 .Fortran 调用之前使用 browser() 来实现这一点。此外,通过指定 INTENT 并设置 NAOK = TRUE(如预期)可以提高速度。肯定会推荐那些。

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

在 R 中使用 glmnet 和 dotCall64 的长向量 的相关文章

  • 如何确定 R 包的作者?

    如何确定包的作者是谁 鉴于我们拥有这个广泛使用的代码库 我认为参考我在分析中使用的软件是合适的 有没有办法以编程方式检索作者和任何其他相关信息 在伪代码中 我想执行以下操作 references base 我怎样才能做到这一点 为了能够引用
  • 如何返回包含最大值标签的向量

    我有一个 4 列数组 我想获得一个向量 其中每行包含包含该行最大值的列的标签 我可以在循环中执行此操作 但我想使用矩阵函数来提高速度 我怎样才能在不编写自己的库函数的情况下做到这一点 有一个函数可以做到这一点 如果x是你的矩阵 尝试max
  • R 中的龙卷风图

    我正在尝试在 R 中绘制龙卷风图 又名敏感性图 目标是可视化某些变量增加 10 和减少 10 的效果 到目前为止我已经得到这个结果 这是我正在使用的代码 Tornado plot data lt matrix c 0 02 0 02 0 0
  • 如何绘制每条线之间具有特定距离的图形

    实际上 我尝试绘制一个图形 但它将所有列 线 放在一起并显示 因此它不具有代表性 我尝试制作模拟数据并向您展示我如何绘制它 并向您展示我想要的内容 我不知道如何制作像下面所示的示例的数据 但我在这里做了什么 set seed 1 M lt
  • 使用 pkg:sjPlot 函数创建一个生成部分斜体单元格的数据框

    我正在尝试创建一个简单的数据表 其中 Coral taxon 列中的属名称为斜体 而 spp 列中的属名称为斜体 属名后面的部分不大写 我尝试使用 expression 函数对 Coral taxon 的每一行进行编码 但没有成功 sum
  • 排序因素与水平

    有人能解释一下 R 中 ordered 参数的用途吗 R says ordered逻辑标志来确定级别是否应被视为有序 按给定的顺序 所以如果我有一个名为名称的因素并设置ordered TRUE names lt factor c fred
  • 如何定义“f_n-chi-square”函数并使用“uniroot”求置信区间?

    I want to get a 95 confidence interval for the following question 我已经写了函数f n在我的 R 代码中 我首先使用 Normal 随机采样 100 个样本 然后定义函数h
  • R - 与 SpatialPolygonsDataFrame 对象相交的 SpatialLinesDataFrame 列表的嵌套循环

    我有一系列需要完成的步骤SpatialLinesDataFrame 此处的 线 基于对象与多特征中各个特征的关系SpatialPolygonsDataFrame 多边形 对象 简而言之 每个线列表元素源自单个面要素内部 并且可能会也可能不会
  • 不同 R/lme4 版本的单一拟合结果不匹配

    我试图将 R 版本 3 5 3 lme4 1 1 18 1 的随机效应估计与 R 版本 4 1 1 lme4 1 1 27 1 相匹配 然而 当存在奇异拟合时 这两个版本之间的随机效应存在微小差异 我对奇点警告很满意 但令人费解的是不同版本
  • 从 df 中提取具有两列的重叠行对

    我想找出这两个表之间哪些对重叠 gt dput data1 structure list Name x c MDH1 MDH1 IDH2 IDH2 IDH2 IDH2 IDH2 IDH2 IDH2 SCOALB SCOALB CSY4 CS
  • 如何在knitr和RStudio中为word和html设置不同的全局选项?

    我正在使用 RStudio 0 98 932 和 knitr 1 6 想要为word和html设置不同的全局knitr选项 例如 想要将word的fig width和fig height设置为6 html的fig width和fig hei
  • 跟踪循环迭代

    抛硬币 成功 你赢100 否则你输50 你会一直玩 直到你口袋里有钱a 的价值如何a在任何迭代中都被存储 a lt 100 while a gt 0 if rbinom 1 1 0 5 1 a lt a 100 else a lt a 50
  • randomForest 包在删除一个预测类时的奇怪行为

    我正在运行一个随机森林模型 它产生的结果从统计角度来看对我来说完全没有意义 因此我确信有些东西mustrandomForest 包的代码出现错误 至少在模型的本次迭代中 预测 左侧变量是具有 3 种可能结果的政党 ID 民主党 独立党 共和
  • 如何在 R 中合并同名列表中的数据框?

    我有一个包含很多数据框的列表 如果它们具有相同的名称 我想合并它们 即合并所有具有相同名称 a 和 b 的数据框 像这样 a lt aaaaa b lt bbbbb c lt ccccc g lt list df1 lt data fram
  • R中的字典数据结构

    在 R 中 我有 例如 gt foo lt list a 1 b 2 c 3 如果我输入foo I get a 1 1 b 1 2 c 1 3 我怎样才能看透foo仅获取 键 列表 在这种情况下 a b c R 列表可以具有命名元素 因此可
  • 将 ftransform 与折叠 R 包中的 fgroup_by 一起使用

    我正在尝试重现以下输出dplyr代码与R包裹collapse dplyr Code library tidyverse starwars gt select name mass species gt group by species gt
  • 正态分布平均值的贝叶斯推理玩具 R 代码 [降雪量数据]

    我有一些降雪观测 x lt c 98 044 107 696 146 050 102 870 131 318 170 434 84 836 154 686 162 814 101 854 103 378 16 256 我被告知它遵循正态分布
  • 警告消息 - 来自 dummies 包的 dummy

    我正在使用 dummies 包为分类变量生成虚拟变量 其中一些变量具有两个以上类别 testdf lt data frame A as factor c 1 2 2 3 3 1 B c A B A B C C C c D D E D D E
  • 如何在 data.table 中分组后使用条件计算行数

    我有以下数据框 dat lt read csv s1 s2 v1 v2 a b 10 20 a b 22 NA a b 13 33 c d 3 NA c d 4 5 NA c d 10 20 dat gt A tibble 6 x 4 gt
  • 如何按用户定义(例如非字母顺序)对数据框进行排序[重复]

    这个问题在这里已经有答案了 给定一个数据框dna gt dna chrom start chr2 39482 chr1 203918 chr1 198282 chrX 7839028 chr17 3874 以下代码重新排序dna by ch

随机推荐