R 中用于大型复杂调查数据集的方法?

2024-01-19

我不是调查方法学家或人口统计学家,但我是 Thomas Lumley 的 R 调查包的狂热粉丝。我一直在处理一个相对较大的复杂调查数据集,即医疗保健成本和利用项目 (HCUP) 国家急诊室样本 (NEDS https://www.hcup-us.ahrq.gov/nedsoverview.jsp)。正如医疗保健研究和质量局所描述的,这是“来自 30 个州 947 家医院的急诊就诊的出院数据,近似于美国医院急诊的 20% 分层样本”

2006 年至 2012 年的完整数据集包含 198,102,435 个观测值。我已将数据分组为 40,073,358 例与外伤相关的出院,其中包含 66 个变量。即使对这些数据运行简单的调查程序也需要非常长的时间。我尝试过使用 RAM(2013 年末的 Mac Pro,3.7GHz 四核,128GB(!)内存),使用多核 http://r-survey.r-forge.r-project.org/survey/html/surveyoptions.html有空的时候,子集化 http://r-survey.r-forge.r-project.org/survey/html/subset.survey.design.html,与一个内存不足的数据库管理系统 https://faculty.washington.edu/tlumley/tutorials/user-biglm.pdf like MonetDB https://github.com/ajdamico/asdfree/blob/da164016bfdd533b12f40b55045d7a6007a24d12/IPUMS%20International/download%20import%20design%20into%20monetdb.R。基于设计的调查程序仍然需要几个小时。有时要好几个小时。一些不太复杂的分析需要 15 个小时以上。我猜测大部分计算工作都与巨大的协方差矩阵有关?

正如人们所预料的那样,处理原始数据的速度要快几个数量级。更有趣的是,根据程序的不同,对于如此大的数据集,未经调整的估计值可能非常接近调查结果。 (参见下面的示例)基于设计的结果显然更精确且更受欢迎,但几个小时的计算时间与几秒钟的计算时间对于增加的精度来说是一个不可忽视的成本。它开始看起来像是绕着街区走了很长一段路。

有没有人有这方面的经验?有没有办法优化大型数据集的 R 调查程序?也许更好地利用并行处理?贝叶斯方法是否使用INLA https://www.stat.washington.edu/research/reports/2011/tr583.pdf or 哈密​​顿量 http://www.stat.columbia.edu/~gelman/research/published/Si_et_al-BA14.pdf像斯坦这样的方法可能是解决方案吗?或者,当调查规模足够大且具有足够代表性时,一些未经调整的估计(尤其是相对指标)是否可以接受?

以下是一些未经调整的估计值近似调查结果的示例。

在第一个示例中,内存中的 svymean 花费了不到一个小时,内存不足则需要 3 个多小时。直接计算只需要不到一秒钟的时间。更重要的是,点估计(svymean 为 34.75,未调整为 34.77)以及标准误差(0.0039 和 0.0037)非常接近。

    # 1a. svymean in memory 

    svydes<- svydesign(
        id = ~KEY_ED ,
        strata = ~interaction(NEDS_STRATUM , YEAR),   note YEAR interaction
        weights = ~DISCWT ,
        nest = TRUE,
        data = inj
    )

    system.time(meanAGE<-svymean(~age, svydes, na.rm=T))
         user   system  elapsed
     3082.131  143.628 3208.822 
     > meanAGE 
           mean     SE
     age 34.746 0.0039 

    # 1b. svymean out of memory
    db_design <-
        svydesign(
            weight = ~discwt ,                                   weight variable column
            nest = TRUE ,                                        whether or not psus are nested within strata
            strata = ~interaction(neds_stratum , yr) ,           stratification variable column
            id = ~key_ed ,                                          
            data = "nedsinj0612" ,                               table name within the monet database
            dbtype = "MonetDBLite" ,
            dbname = "~/HCUP/HCUP NEDS/monet"  folder location
        )

    system.time(meanAGE<-svymean(~age, db_design, na.rm=T))
          user    system   elapsed
     11749.302   549.609 12224.233
     Warning message:
     'isIdCurrent' is deprecated.
     Use 'dbIsValid' instead.
     See help("Deprecated")
           mean     SE
     age 34.746 0.0039 


    # 1.c unadjusted mean and s.e.
    system.time(print(mean(inj$AGE, na.rm=T)))
     [1] 34.77108
        user  system elapsed
       0.407   0.249   0.653
      sterr <- function(x) sd(x, na.rm=T)/sqrt(length(x))  # write little function for s.e.
     system.time(print(sterr(inj$AGE)))
     [1] 0.003706483
        user  system elapsed
       0.257   0.139   0.394 

svymean 与使用 svyby(近 2 小时)与 tapply(4 秒左右)应用于数据子集的平均值的结果之间存在类似的对应关系:

# 2.a svyby .. svymean
system.time(AGEbyYear<-svyby(~age, ~yr, db_design, svymean, na.rm=T, vartype = c( 'ci' , 'se' )))
     user   system  elapsed
 4600.050  376.661 6594.196 
        yr      age          se     ci_l     ci_u
 2006 2006 33.83112 0.009939669 33.81163 33.85060
 2007 2007 34.07261 0.010055909 34.05290 34.09232
 2008 2008 34.57061 0.009968646 34.55107 34.59014
 2009 2009 34.87537 0.010577461 34.85464 34.89610
 2010 2010 35.31072 0.010465413 35.29021 35.33124
 2011 2011 35.33135 0.010312395 35.31114 35.35157
 2012 2012 35.30092 0.010313871 35.28071 35.32114


# 2.b tapply ... mean
system.time(print(tapply(inj$AGE, inj$YEAR, mean, na.rm=T)))
     2006     2007     2008     2009     2010     2011     2012
 33.86900 34.08656 34.60711 34.81538 35.27819 35.36932 35.38931
    user  system elapsed
   3.388   1.166   4.529

system.time(print(tapply(inj$AGE, inj$YEAR, sterr)))
        2006        2007        2008        2009        2010        2011        2012
 0.009577755 0.009620235 0.009565588 0.009936695 0.009906659 0.010148218 0.009880995
    user  system elapsed
   3.237   0.990   4.186

调查和未调整结果之间的对应关系开始因绝对计数而崩溃,这需要编写一个吸引调查对象的小函数,并使用 Lumley 博士的一些代码来对计数进行加权:

# 3.a svytotal

system.time(print(svytotal(~adj_cost, svydes, na.rm=T)))
             total       SE
adj_cost 9.975e+10 26685092
     user    system   elapsed 
10005.837   610.701 10577.755 

# 3.b "direct" calculation

SurvTot<-function(x){
    N <- sum(1/svydes$prob)
    m <- mean(x, na.rm = T)
    total <- m * N
    return(total)
}

> system.time(print(SurvTot(inj$adj_cost)))
[1] 1.18511e+11
   user  system elapsed 
  0.735   0.311   0.989 

结果更难以让人接受。尽管仍在调查程序确定的误差范围内。但同样,为了获得更精确的结果,3 小时与 1 秒相比,成本相当可观。

更新:2016 年 2 月 10 日

感谢塞维林和安东尼允许我借用你们的突触。抱歉延迟跟进,花了很少的时间来尝试您的建议。

Severin,您的观察是正确的,革命分析/MOR 构建对于某些操作来说更快。看起来它与 CRAN R 附带的 BLAS(“基本线性代数子程序”)库有关。它更精确,但速度较慢。因此,我使用允许多线程的专有(但 Mac 上免费)Apple Accelerate vecLib 优化了我的机器上的 BLAS(请参阅http://blog.quadrivio.com/2015/06/improved-r-performance-with-openblas.html http://blog.quadrivio.com/2015/06/improved-r-performance-with-openblas.html)。这似乎减少了一些操作时间,例如从 svyby/svymean 的 3 小时到 2 小时多一点。

安东尼在复制重量设计方法方面运气不佳。 type="bootstrap" withreplicates=20 运行了大约 39 小时,然后我退出了; type =“BRR”返回错误“无法在层中分割奇数个 PSU”,当我将选项设置为small =“merge”,large =“merge”时,它运行了几个小时,然后操作系统抛出了一个错误巨大的叹息,耗尽了应用程序内存; type="JKn" 返回错误“无法分配大小为 11964693.8 Gb 的向量”

再次非常感谢您的建议。现在,我将让自己在很长一段时间内零碎地进行这些分析。如果我最终想出更好的方法,我会发布在SO上


对于巨大的数据集,线性化设计(svydesign)比复制设计慢得多(svrepdesign)。检查其中的加权函数survey::as.svrepdesign并使用其中之一直接进行复制设计。您不能使用线性化来完成此任务。你可能甚至不使用会更好as.svrepdesign而是使用其中的函数。

举个例子,使用cluster=, strata=, and fpc=直接进入重复加权设计,参见

https://github.com/ajdamico/asdfree/blob/master/Censo%20Demografico/download%20and%20import.R#L405-L429 https://github.com/ajdamico/asdfree/blob/master/Censo%20Demografico/download%20and%20import.R#L405-L429

请注意,您还可以在此处查看每分钟的速度测试(带有每个事件的时间戳)http://monetdb.cwi.nl/testweb/web/eanthony/ http://monetdb.cwi.nl/testweb/web/eanthony/

还要注意的是replicates=参数几乎 100% 决定了设计的运行速度。因此,也许可以进行两种设计,一种用于系数(只需几次重复),另一种用于SE(具有您可以容忍的尽可能多的值)。以交互方式运行您的系数并优化白天所需的数字,然后让需要 SE 计算的更大进程在夜间运行

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

R 中用于大型复杂调查数据集的方法? 的相关文章

  • 在ggplotly散点图中添加自定义数据标签

    我想显示Species对于每个数据点 当光标位于该点上方而不是 x 和 y 值时 我用iris数据集 另外 我希望能够单击数据点以使标签持久存在 并且当我在图中选择新位置时标签不会消失 如果可能的话 最基本的是标签 持久性问题是一个优点 这
  • 栅格堆叠后如何写入?

    我想操作几个光栅文件 然后再次写入它们 rasterfiles lt list files C data envi full names TRUE d1 lt overlay stack rasterfiles fun function x
  • R lubridate:当地语言的工作日

    如何获取本地语言的工作日和月份 My code library lubridate data lt c 10 02 2015 11 03 2015 data lubri lt dmy data wday data lubri label T
  • 将 read.csv 与符号链接文件一起使用

    我正在尝试做什么 我的源文件非常大 我想避免将其复制到其他文件夹中 我决定创建一个指向大文件的符号链接并想使用read csv读取文件 文件夹结构 项目1 数据 源文件 csv 项目2 数据 别名到源文件 csv 什么地方出了错 读取源文件
  • 如何将 R 数据框中的多个字符列合并为单个列

    我正在处理人口普查数据 需要将四个字符列合并为一列 Example LOGRECNO STATE COUNTY TRACT BLOCK 60 01 001 021100 1053 61 01 001 021100 1054 62 01 00
  • 使用管道语法处理模型列表

    我经常喜欢拟合和检查与 R 数据框中的两个变量相关的多个模型 我可以使用如下语法来做到这一点 require tidyverse require broom models lt list hp exp cyl hp cyl map df m
  • 如何在 R 中只为直方图的一个标签着色?

    我有一个像这样的数据框 CellLines ZEB1 600MPE 2 8186 AU565 2 783 BT20 2 7817 BT474 2 6433 BT483 2 4994 BT549 3 035 CAMA1 2 718 DU447
  • rpart是自动剪枝吗?

    Is rpart自动修剪 生成的决策树rpart比具有自动修剪功能的 Oracle Data Mining 生成的级别要多得多 否 但拟合函数的默认值可能会 提前 停止分割 对于 早期 的某些定义 See rpart control对于您可
  • 使用 readHTMLTable 从 https 网页读取表格

    我安装了 R 3 3 1 并使用 RStudio 0 99 903 我正在尝试从以下 URL 将表格读入 R https www fantasypros com nfl rankings consensus cheatsheets php
  • stat_function 从函数生成平线

    我有以下代码 library ggplot2 f lt function x if x gt 2 1 x 0 3 else 0 graph lt ggplot data frame x c 0 10 aes x graph lt graph
  • 使用自定义渐变填充直方图箱

    我想在 R 和 ggplot2 中创建一个直方图 其中根据连续的 x 值填充箱 大多数教程仅通过离散值或密度 计数进行着色 下列的这个例子 https stackoverflow com questions 40284227 how to
  • 改进R中从google获取股票新闻数据的功能

    我已经编写了一个函数来从 Google 获取和解析给定股票代码的新闻数据 但我确信有一些方法可以改进它 对于初学者来说 我的函数返回一个 GMT 时区的对象 而不是用户当前的时区 如果传递的数字大于 299 它就会失败 可能是因为 goog
  • 如何使用autoconf重新生成配置文件?

    我使用 autoconf 重新生成配置文件 它有效 但是当我执行生成的配置文件时 configure 有一些错误消息 例如 configure line 3713 syntax error near unexpected token bla
  • R 错误:无法更改锁定绑定的值

    我试图估计无限数字流的平均值和标准差 当我运行代码时 出现错误消息 无法更改锁定绑定的值 我做了一些研究 发现这个错误与我使用全局变量有关 但我无法弄清楚 任何帮助将非常感激 在此先感谢您的帮助 define global variable
  • RStudio 不会通过 rPython 调用加载所有 Python 模块

    我从 Bash 和 RStudio 中运行相同的脚本时出现一些意外行为 请考虑以下事项 我有一个文件夹 rpython 包含两个脚本 test1 R library rPython setwd rpython python load tes
  • R参考类问题

    我正在尝试在 R 中创建一个简单的参考类 这是我的代码 R 初学者 MyClass lt setRefClass MyClass fields list a numeric b numeric methods list initialize
  • 函数“[<-”将_替换_一个元素,但不会追加_元素_

    我在使用时注意到以下几点 lt 我成功于替换元素但不位于追加向量的一个元素 例子 VarX lt integer VarX 1 lt 11 lt VarX 2 22 VarX 1 11 Expected the value of VarX
  • R 中使用 `UseMethod()` 与 `inherits()` 来确定对象的类

    如果我需要根据 R 对象的类以不同的方式处理它们 我可以使用if and else在单个函数内 foo lt function x if inherits x list Foo the list else if inherits x num
  • R Leaflet Legend:colorBin-删除中断之间的小数

    我正在使用 Leaflet 库在 R 中创建交互式 HTML 地图 传说中采用的是colorBin用于创建将数据分为 6 个类别的方法 使用min values and max values 我已经定义了美国社区调查收入数据的特定范围可能落
  • 通过 R 中的数据子集执行计算

    我想对数据框的 PERMNO 列中的每个公司编号进行计算 其摘要可以在此处查看 gt summary companydataRETS PERMNO RET Min 10000 Min 0 971698 1st Qu 32716 1st Qu

随机推荐