R 中给定出生日期和任意日期的有效且准确的年龄计算(以年、月或周为单位)

2023-12-06

我面临着计算给定出生日期和任意日期的年龄(以年、月或周为单位)的常见任务。问题是,我经常必须对许多记录(> 3 亿)执行此操作,因此性能是这里的一个关键问题。

在 SO 和 Google 中快速搜索后,我找到了 3 个替代方案:

  • 常见的算术过程 (/365.25) (link)
  • 使用函数new_interval() and duration()从包装中lubridate (link)
  • 功能age_calc()从包装中eeptools (link, link, link)

所以,这是我的玩具代码:

# Some toy birthdates
birthdate <- as.Date(c("1978-12-30", "1978-12-31", "1979-01-01", 
                       "1962-12-30", "1962-12-31", "1963-01-01", 
                       "2000-06-16", "2000-06-17", "2000-06-18", 
                       "2007-03-18", "2007-03-19", "2007-03-20", 
                       "1968-02-29", "1968-02-29", "1968-02-29"))

# Given dates to calculate the age
givendate <- as.Date(c("2015-12-31", "2015-12-31", "2015-12-31", 
                       "2015-12-31", "2015-12-31", "2015-12-31", 
                       "2050-06-17", "2050-06-17", "2050-06-17",
                       "2008-03-19", "2008-03-19", "2008-03-19", 
                       "2015-02-28", "2015-03-01", "2015-03-02"))

# Using a common arithmetic procedure ("Time differences in days"/365.25)
(givendate-birthdate)/365.25

# Use the package lubridate
require(lubridate)
new_interval(start = birthdate, end = givendate) / 
                     duration(num = 1, units = "years")

# Use the package eeptools
library(eeptools)
age_calc(dob = birthdate, enddate = givendate, units = "years")

我们稍后讨论准确性,首先关注性能。这是代码:

# Now let's compare the performance of the alternatives using microbenchmark
library(microbenchmark)
mbm <- microbenchmark(
    arithmetic = (givendate - birthdate) / 365.25,
    lubridate = new_interval(start = birthdate, end = givendate) /
                                     duration(num = 1, units = "years"),
    eeptools = age_calc(dob = birthdate, enddate = givendate, 
                        units = "years"),
    times = 1000
)

# And examine the results
mbm
autoplot(mbm)

结果如下:

Microbenchmark results - table Microbenchmark results - plot

底线:性能lubridate and eeptools函数比算术方法差很多(/365.25至少快10倍)。不幸的是,算术方法不够准确,我无法承受这种方法所犯的一些错误。

“因为现代公历的方式 是构造出来的,没有简单的算术 产生一个人的年龄的方法,根据 常见用法——常见用法意味着一个人的 年龄应该始终是一个恰好在 一个生日”。 (link)

当我读到一些帖子时,lubridate and eeptools不要犯这样的错误(尽管,我还没有查看代码/阅读有关这些函数的更多信息以了解它们使用哪种方法),这就是我想使用它们的原因,但它们的性能不适用于我的实际应用程序。

关于有效且准确的年龄计算方法有什么想法吗?

EDIT

哦,看来lubridate也会犯错误。显然,基于这个玩具示例,它比算术方法犯的错误更多(参见第 3、6、9、12 行)。 (难道我做错了什么?)

toy_df <- data.frame(
    birthdate = birthdate,
    givendate = givendate,
    arithmetic = as.numeric((givendate - birthdate) / 365.25),
    lubridate = new_interval(start = birthdate, end = givendate) /
        duration(num = 1, units = "years"),
    eeptools = age_calc(dob = birthdate, enddate = givendate,
                        units = "years")
)
toy_df[, 3:5] <- floor(toy_df[, 3:5])
toy_df

    birthdate  givendate arithmetic lubridate eeptools
1  1978-12-30 2015-12-31         37        37       37
2  1978-12-31 2015-12-31         36        37       37
3  1979-01-01 2015-12-31         36        37       36
4  1962-12-30 2015-12-31         53        53       53
5  1962-12-31 2015-12-31         52        53       53
6  1963-01-01 2015-12-31         52        53       52
7  2000-06-16 2050-06-17         50        50       50
8  2000-06-17 2050-06-17         49        50       50
9  2000-06-18 2050-06-17         49        50       49
10 2007-03-18 2008-03-19          1         1        1
11 2007-03-19 2008-03-19          1         1        1
12 2007-03-20 2008-03-19          0         1        0
13 1968-02-29 2015-02-28         46        47       46
14 1968-02-29 2015-03-01         47        47       47
15 1968-02-29 2015-03-02         47        47       47

lubridate 出现上述错误的原因是您正在计算持续时间(两个瞬间之间发生的确切时间量,其中 1 年 = 31536000 秒),而不是周期(两个瞬间之间发生的时钟时间变化)。

要获取时钟时间的变化(以年、月、日等为单位),您需要使用

as.period(interval(start = birthdate, end = givendate))

给出以下输出

 "37y 0m 1d 0H 0M 0S"   
 "37y 0m 0d 0H 0M 0S"   
 "36y 11m 30d 0H 0M 0S" 
 ...
 "46y 11m 30d 1H 0M 0S" 
 "47y 0m 0d 1H 0M 0S"   
 "47y 0m 1d 1H 0M 0S" 

要提取年份,您可以使用以下命令

as.period(interval(start = birthdate, end = givendate))$year
#or
lubridate::year(as.period(interval(start = birthdate, end = givendate)))

 [1] 37 37 36 53 53 52 50 50 49  1  1  0 46 47 47 

不幸的是,请注意,看起来比上面的方法还要慢!

> mbm
Unit: microseconds
       expr       min        lq       mean    median         uq        max neval cld
 arithmetic   116.595   138.149   181.7547   184.335   196.8565   5556.306  1000  a 
  lubridate 16807.683 17406.255 20388.1410 18053.274 21378.8875 157965.935  1000   b
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R 中给定出生日期和任意日期的有效且准确的年龄计算(以年、月或周为单位) 的相关文章

  • 在 Shiny 中设置一个绘图缩放以匹配另一个绘图缩放

    我正在尝试使用情节重排获取一个图的 x 轴缩放限制 并将它们应用到 Shiny 中的另一个图 到目前为止 我可以从 plot1 x轴限制 获取相关的plotly relayout数据 将其转换 从数字到日期 并在绘制 plot2 之前将其提
  • 有没有办法在 RStudio 中调试 RScript 调用?

    假设我从命令行运行 R 脚本 如下所示 Rscript prog R x y z 我想检查某一行的代码 目前 我无法在 RStudio 中以交互方式调试它 因为我不知道如何传递参数 由于它设计为从命令行运行 因此如何通过命令行 RStudi
  • 可以明确声明包依赖项的版本吗?

    我倾向于对我编写的代码进行明确而不是隐含的描述 因此 在成功创建自己的包之后 我立即想到的下一件事是如何最好地确保代码的健壮性和可靠性 其中一部分与我的包所依赖的包有关 实际问题 在这方面 是否可以明确声明需要 期望哪个版本的包依赖项 我正
  • 将密度曲线拟合到 R 中的直方图

    R中有没有可以将曲线拟合到直方图的函数 假设您有以下直方图 hist c rep 65 times 5 rep 25 times 5 rep 35 times 10 rep 45 times 4 看上去很正常 但其实是歪曲的 我想拟合一条倾
  • 如何使用 r 中的 caret 包在最佳调整超参数的 10 倍交叉验证中获得每次折叠的预测?

    我试图使用 R 中的插入符包使用 10 倍交叉验证和 3 次重复来运行 SVM 模型 我想使用最佳调整的超参数获得每次折叠的预测结果 我正在使用以下代码 Load packages library mlbench library caret
  • 如何在不循环的情况下添加组ID?

    我有数据框 例如 productid ordernum p1 10 p2 20 p3 30 p4 5 p5 20 p6 8 我想添加另一列 称为 groupid 它将产品按顺序分组在一起 一旦 sum ordernum 达到 30 分配一个
  • 如何使用 R 中带引号的字符值内的序列读取 CSV?

    这是一个包含两个字符列的 CSV 文件 key value a 所有字符值都用双引号引起来 并且有一个顺序 在值之一内 转义引号加分隔符 我无法通过 read csv readr 中的 read csv 或 data table 中的 fr
  • 在函数内部调用 clusterApply 时,性能会下降

    我遇到了一个奇怪的问题clusterApply 我已经能够尽可能地隔离它 如下所示 首先 我从全局环境运行以下代码 require parallel cl lt makeCluster rep localhost 20 SOCK xl lt
  • 将列表中的列转换为 R 中的数据框

    我有使用 R 创建的以下列表 set seed 326581 X1 rnorm 10 0 1 Y1 rnorm 10 0 2 data data frame X1 Y1 lst lt replicate 100 df smpl lt dat
  • ggplot 中的错误问题:“grid.Call(”L_textBounds“, as.graphicsAnnot(x$label), x$x, x$y, … 中的错误”[重复]

    这个问题在这里已经有答案了 我试图在 ggplot 中制作一个条形图 其中我通过强制其中一些标签为长度为零的字符串 即 来指定要显示的标签 但是 我收到错误 Error in grid Call L textBounds as graphi
  • 在另一个 Rmd 中运行选定的块

    我已经在源 Rmd 文件中运行了分析 并且希望仅使用few来自源的块 我已经看到了一些关于从源 Rmd 中提取所有块的答案来自另一个 Rmd 中的 Rmd 文件的源代码 https stackoverflow com questions 4
  • 根据另一列中的键累积一列中的值时出现问题

    我有一个看起来像这样的数据框 我需要使用 PROJ ID 列中的字符串创建一个新的值列 并形成 PROJ NAME 列中的值字符串 这里提供的解决方案 根据 r 中另一列的键累积一列中的值 https stackoverflow com q
  • 如何更改 Shiny 中 navbarPage 折叠的断点

    我想用shiny navbarPage collapsible TRUE 当在小屏幕上查看我的 Shiny 应用程序时 将导航元素折叠到菜单中 默认情况下 当浏览器宽度小于 940 像素时会触发折叠 有什么方法可以改变这一点 以便在稍大的浏
  • 比较 R 中的两个字符向量

    我有两个 ID 字符向量 我想比较这两个字符向量 特别是我对以下数字感兴趣 A和B各有多少个ID 有多少个ID在A中但不在B中 有多少个ID在B但不在A 我还想画维恩图 以下是一些可以尝试的基础知识 gt A c Dog Cat Mouse
  • 使用 R 进行项目组织 [重复]

    这个问题在这里已经有答案了 可能的重复 统计分析和报告撰写的工作流程 https stackoverflow com questions 1429907 workflow for statistical analysis and repor
  • 使用outer代替expand.grid

    我正在寻找尽可能快的速度并留在基地做该做的事expand grid做 我用过outer为过去类似的目的创建一个向量 像这样的东西 v lt outer letters LETTERS paste0 unlist v lower tri v
  • R:将 JSON 时间格式转换为 POSIX

    我有一个 JSON 字符串 并将其放入数据框中 我能够做到这一点 但我在使用 apply 函数之一将所有时间字符串转换为 POSIX 格式时遇到问题 See here https stackoverflow com questions 90
  • 如何在R中同时对三个字段进行网络分析

    如何在 R 中同时对三个字段进行网络分析 下面是示例数据以及desired output在最后一栏中 df lt data frame stringsAsFactors FALSE id 1 c ABC ABC BCD CDE DEF EF
  • R 中的 Websocket

    我设法在 R 中建立到 Mtgox websocket 的连接 规格如下 url https socketio mtgox com mtgox Currency USD https socketio mtgox com mtgox Curr
  • GGPLOT2:如何在 ggplot() 脚本中绘制特定选择

    这是一个名为的大型数据集的峰值P 其中有 10 个优惠 CS 有不同的商店 SHP 具有多个数值 数据集列出了按周排序的它们 WK 2 tm 52 它创建一个大文件 仅前 6 行出现峰值 WK MND CS SHP RevCY RevLY

随机推荐

  • 尽管我有外部临时地址,但 gcloud 计算地址列表返回 0 结果

    我的项目中有一个带有外部 IP 的 google 计算实例 实例上的描述命令向我显示 networkInterfaces accessConfigs kind compute accessConfig name External NAT n
  • 从android中的sqlite数据库检索数据时出现运行时错误

    我正在尝试使用 sqlite 在 eclipse 中从数据库插入和检索数据 但它显示了RuntimeError 我创建了一个布局 其中包含三个编辑文本和一个按钮来创建简单信息 但没有创建任何内容 我使用以下代码创建java数据库 packa
  • NSURLRequest挂SpringBoard

    我有一个 MobileSubstrate 插件 可以挂钩跳板 不是在实际的 Objective C 代码中 而是在 plist 中 它包含一个 UIWebView 它加载一个 NSURLRequest 这个 NSURLRequest 在这里
  • CSS:固定到底部并居中

    我需要将页脚固定在页面底部并将其居中 页脚的内容可能随时变化 所以我不能仅仅通过 margin left xxpx 将其居中 右边距 xxpx 问题是由于某种原因这不起作用 whatever position fixed bottom 0p
  • 将 ArrayList 制作为 JTable

    我有一个 ArrayList
  • 如何从源代码为任何应用程序创建数据流图 (DFG/SDFG)

    我做了很多研究来弄清楚如何从源代码为应用程序创建 DFG DFG 可在线用于某些应用程序 例如 MP3 解码器 JPEG 压缩和 H 263 解码器 我一直无法弄清楚如何从源代码为 HEVC 等应用程序创建 DFG 是否有任何工具可以立即为
  • Datastax DSE 5.1 搜索是否支持 facet.pivot 中使用的 Solr 本地参数

    据我了解 DSE 5 1 运行 Solr 6 0 版本 我正在尝试使用 Solr 本地参数来使用 facet pivot 功能 但它似乎不起作用 我的数据如下简单4个字段 我需要的是按名称字段对结果进行分组 以便获得每年的总和 钱 我相信带
  • Android 上的 OpenGL 深度缓冲区

    我目前正在 Android 2 1 上学习 OpenGL ES 编程 我从强制性的旋转立方体开始 它旋转得很好 但我无法让深度缓冲区工作 多边形始终按照 GL 命令渲染它们的顺序显示 我在 GL 初始化期间执行此操作 gl glClearC
  • 安装Maven 3后mvn无法识别

    我的 Maven 3 安装有一些问题 我已经下载了maven 3 0 3并将其解压到一个文件夹中 我设置了以下环境变量 M2 HOME C a few folders apache maven 3 0 3 M2 M2 HOME bin JA
  • 更改 JtextPane 中的鼠标指针

    我有一个JTextPane其内容类型为文本 纯文本 我为此设置了一些文本JTextPane它包含一些显示的文本URLs 当我将鼠标指向该文本时 我想仅将鼠标指针更改为手形指针 这个功能可以实现吗 注 我有以下内容JTextPane as t
  • 对于 DynamicComponentLoader,@ContentChild 为 null

    我有一个可在许多页面上使用的侧面导航组件 这不是单页网络应用程序 它动态加载到切换菜单的父组件上 ContentChild 用于获取子组件的句柄 以便可以通过设置 input overrideHidden 来切换子组件 问题是 Conten
  • Ruby/Watir:firefox 无头

    根据这个 https developer mozilla org en US Firefox Headless modefirefox 57 能够以无头模式运行 我尝试将它与此一起使用 omg3r Watir Browser new fir
  • 堆栈跟踪是如何生成的?

    程序中没有任何一个方法 知道 它在堆栈上的位置 它所知道的只是它自己的小工作 它完成了它并返回 那么 当抛出异常并打印堆栈跟踪时 这是从哪里来的呢 JVM 中是否隐式有一个单独的线程与每个应用程序一起运行来监视程序的状态 或者 JVM 本身
  • Google表格:删除包含指定数据的行

    我是 Java 脚本和 Google Apps 脚本的新手 所以如果这个问题已经得到解答 我很抱歉 在从事这个项目的最后几个月里 我无法找到我想要的东西 我正在这里编写脚本的变体 如果在单元格中找到特定 单词 则删除 Google 表格中的
  • 在类型转换中,类型“List”不是类型“List”的子类型

    运行后飞镖迁移 应用空安全性 该错误在我的代码中弹出 我认为这是导致代码块的错误 LayoutBuilder builder context cons return GestureDetector child new Stack child
  • 由于谷歌自动服务处理器,无法编译我的 javafx 和 selenium 项目(“无法获取公共无参数构造函数”)

    我正在尝试使用 Maven 编译我的 Instagram 机器人 它使用javafx作为接口 使用selenium作为自动化 我已经被这个错误困扰了很长时间 当我尝试做的时候mvn clean javafx jlink它向我显示了这个错误
  • MYSQL 无法从 PHP 接收数据

    我正在尝试将数据从输入发送到我的 sql 数据库 这是它尝试将信息发送到数据库的编码 它不会出现在数据库中 编码有什么问题
  • 如何将密码从md5转换为laravel加密方法

    我想将现有项目重新开发为 laravel 在我的旧系统中 我将密码存储到 md5 中 现在我如何根据现有用户的 laravel 哈希方法将其转换 有什么直接的方法可以做到吗 有什么直接的方法可以做到吗 不 没有直接的方法 但你可以通过重写来
  • 禁用 CMake 选项没有效果

    我正在准备一个应用程序 它应该在有或没有 GUI 的情况下工作 所以我在 CMakeLists txt 中使用命令 option NEED GUI Include Qt support OFF and if NEED GUI message
  • R 中给定出生日期和任意日期的有效且准确的年龄计算(以年、月或周为单位)

    我面临着计算给定出生日期和任意日期的年龄 以年 月或周为单位 的常见任务 问题是 我经常必须对许多记录 gt 3 亿 执行此操作 因此性能是这里的一个关键问题 在 SO 和 Google 中快速搜索后 我找到了 3 个替代方案 常见的算术过