将观察结果与重叠日期相结合

2023-12-31

我的数据框中的每个观察结果都包含不同的“日期之前”和“日期之后实例”。问题是每个 ID 的某些日期重叠。例如,在下表中,ID 1 和 4 包含重叠的日期值。

ID  before date after date
1   10/1/1996   12/1/1996
1   1/1/1998    9/30/2003
1   1/1/2000    12/31/2004
2   1/1/2001    3/31/2006
3   1/1/2001    9/30/2006
4   1/1/2001    9/30/2005
4   10/1/2004   12/30/2004
4   10/3/2004   11/28/2004

我正在尝试得到这样的东西:

ID  before date after date
1   10/1/1996   12/1/1996
1   1/1/1998    12/31/2004
2   1/1/2001    3/31/2006
3   1/1/2001    9/30/2006
4   1/1/2001    9/30/2005

基本上,我想将任何重叠的日期值替换为重叠值的日期范围,保留不重叠的值,并删除任何不必要的行。不知道该怎么做


首先,您应该将字符串日期转换为Date- 分类值,这将使比较成为可能。以下是我定义和强制您的数据的方式:

df <- data.frame(ID=c(1,1,1,2,3,4,4,4), before.date=c('10/1/1996','1/1/1998','1/1/2000','1/1/2001','1/1/2001','1/1/2001','10/1/2004','10/3/2004'), after.date=c('12/1/1996','9/30/2003','12/31/2004','3/31/2006','9/30/2006','9/30/2005','12/30/2004','11/28/2004') );
dcis <- grep('date$',names(df));
df[dcis] <- lapply(df[dcis],as.Date,'%m/%d/%Y');
df;
##   ID before.date after.date
## 1  1  1996-10-01 1996-12-01
## 2  1  1998-01-01 2003-09-30
## 3  1  2000-01-01 2004-12-31
## 4  2  2001-01-01 2006-03-31
## 5  3  2001-01-01 2006-09-30
## 6  4  2001-01-01 2005-09-30
## 7  4  2004-10-01 2004-12-30
## 8  4  2004-10-03 2004-11-28

现在,我的解决方案涉及计算一个“重叠分组”向量,我称之为og。它假设输入df是由ID进而before.date,它位于您的示例数据中。如果没有,这可以通过以下方式实现df[order(df$ID,df$before.date),]。这是我的计算方法og:

cummax.Date <- function(x) as.Date(cummax(as.integer(x)),'1970-01-01');
og <- with(df,c(0,cumsum(!(ID[-length(ID)]==ID[-1] & ave(after.date,ID,FUN=cummax)[-length(after.date)]>before.date[-1]))));
og;
## [1] 0 1 1 2 3 4 4 4

不幸的是,基础Rcummax()功能不起作用Date- 分类对象,所以我必须写一个cummax.Date()垫片。我将解释一下需要ave() and cummax()业务在帖子末尾。

正如您所看到的,通过排除第一个元素,上述计算滞后于两个向量化比较中每一个的 RHS[-1]。这使我们能够比较记录的ID与以下记录相等ID,并比较是否是after.date是在之后before.date以下记录。得到的逻辑向量进行 AND 运算 (&) 一起。然后,该逻辑向量的否定表示相邻的记录对not重叠,因此我们可以cumsum()结果(并在前面添加零,因为第一个记录必须以零开头)以获得我们的分组向量。

最后,对于解决方案的最后一部分,我使用了by()独立与每个重叠组合作:

do.call(rbind,by(df,og,function(g) transform(g[1,],after.date=max(g$after.date))));
##   ID before.date after.date
## 0  1  1996-10-01 1996-12-01
## 1  1  1998-01-01 2004-12-31
## 2  2  2001-01-01 2006-03-31
## 3  3  2001-01-01 2006-09-30
## 4  4  2001-01-01 2005-09-30

由于组中的所有记录必须具有相同的ID,并且我们假设记录按以下顺序排序before.date(在被订购后ID,不再相关),我们可以得到正确的ID and before.date组中第一条记录的值。这就是为什么我开始g[1,]。那么我们只需要得到最大的after.date从小组通过max(g$after.date),并覆盖第一条记录after.date与此,我已经完成了transform().

关于性能的一句话:关于排序的假设有助于提高性能,因为它允许我们通过滞后矢量化比较简单地将每个记录与紧随其后的记录进行比较,而不是将组中的每个记录与其他记录进行比较。

现在,对于ave() and cummax()商业。在写完答案的初始版本后,我意识到我的解决方案存在缺陷,而您的示例数据恰好没有暴露该缺陷。假设一组中有 3 个记录。如果第一条记录的范围与both下面两条记录,然后中间的记录not与第三条记录重叠,那么我的(原始)代码将无法识别第三条记录是前两条记录的同一重叠组的一部分。

解决方案不是简单地使用after.date与后续记录进行比较时使用当前记录,而是使用累积最大值after.date组内。如果任何较早的记录完全超出了紧随其后的记录,那么它显然与该记录重叠,并且它的after.date在考虑后续记录的重叠组时重要的是。

这是需要此修复的输入数据的演示,使用您的df作为基础:

df2 <- df;
df2[7,'after.date'] <- '2004-10-02';
df2;
##   ID before.date after.date
## 1  1  1996-10-01 1996-12-01
## 2  1  1998-01-01 2003-09-30
## 3  1  2000-01-01 2004-12-31
## 4  2  2001-01-01 2006-03-31
## 5  3  2001-01-01 2006-09-30
## 6  4  2001-01-01 2005-09-30
## 7  4  2004-10-01 2004-10-02
## 8  4  2004-10-03 2004-11-28

现在记录 6 与记录 7 和 8 都重叠,但记录 7 不与记录 8 重叠。该解决方案仍然有效:

cummax.Date <- function(x) as.Date(cummax(as.integer(x)),'1970-01-01');
og <- with(df2,c(0,cumsum(!(ID[-length(ID)]==ID[-1] & ave(after.date,ID,FUN=cummax)[-length(after.date)]>before.date[-1]))));
og;
## [1] 0 1 1 2 3 4 4 4
do.call(rbind,by(df2,og,function(g) transform(g[1,],after.date=max(g$after.date))));
##   ID before.date after.date
## 0  1  1996-10-01 1996-12-01
## 1  1  1998-01-01 2004-12-31
## 2  2  2001-01-01 2006-03-31
## 3  3  2001-01-01 2006-09-30
## 4  4  2001-01-01 2005-09-30

这是一个证明og如果没有ave()/cummax() fix:

og <- with(df2,c(0,cumsum(!(ID[-length(ID)]==ID[-1] & after.date[-length(after.date)]>before.date[-1]))));
og;
## [1] 0 1 1 2 3 4 4 5

对解决方案进行小调整,覆盖after.date提前og计算,并避免max()调用(如果您打算覆盖原始内容,则更有意义df使用新的聚合):

cummax.Date <- function(x) as.Date(cummax(as.integer(x)),'1970-01-01');
df$after.date <- ave(df$after.date,df$ID,FUN=cummax);
df;
##   ID before.date after.date
## 1  1  1996-10-01 1996-12-01
## 2  1  1998-01-01 2003-09-30
## 3  1  2000-01-01 2004-12-31
## 4  2  2001-01-01 2006-03-31
## 5  3  2001-01-01 2006-09-30
## 6  4  2001-01-01 2005-09-30
## 7  4  2004-10-01 2005-09-30
## 8  4  2004-10-03 2005-09-30
og <- with(df,c(0,cumsum(!(ID[-length(ID)]==ID[-1] & after.date[-length(after.date)]>before.date[-1]))));
og;
## [1] 0 1 1 2 3 4 4 4
df <- do.call(rbind,by(df,og,function(g) transform(g[1,],after.date=g$after.date[nrow(g)])));
df;
##   ID before.date after.date
## 0  1  1996-10-01 1996-12-01
## 1  1  1998-01-01 2004-12-31
## 2  2  2001-01-01 2006-03-31
## 3  3  2001-01-01 2006-09-30
## 4  4  2001-01-01 2005-09-30
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将观察结果与重叠日期相结合 的相关文章

随机推荐

  • 位运算与

    这是一个leetcode问题 给定一个数字数组 nums 其中恰好有两个元素仅出现一次 而所有其他元素恰好出现两次 找出只出现一次的两个元素 例如 给定 nums 1 2 1 3 2 5 返回 3 5 我的代码是 class Solutio
  • 使用bash,如何删除特定目录中所有文件的扩展名?

    我想保留这些文件但删除它们的扩展名 这些文件的扩展名不同 我的最终目标是删除它们的所有扩展并将它们更改为我选择的一个扩展 我已经把第二部分写下来了 到目前为止我的代码 bin bash echo n Enter the directory
  • 寻找在过程中保持大小并清除旧元素的数据结构

    Usecase维护最后 n 个访问过的 URL 的列表 其中 n 是固定数字 当新的 URL 添加到列表中时 旧的 URL 会自动删除 以使其保持在 n 个元素 要求数据结构需要按时间排序 如果接受 Comparator 应该没问题 你需要
  • 如何遍历 N 叉树

    我的树 节点类 import java util ArrayList import java util List public class Node
  • 如果未安装应用程序,则重定向到应用程序商店

    场景是用户将获得他的电子邮件的链接 如果用户单击链接 如果应用程序已安装 则应用程序应打开 如果应用程序未安装 则应重定向到应用程序商店 我已经看到了深度链接的实现 但我相信它也需要在后端进行更多的实现 任何人都可以帮忙解决这个问题吗 如果
  • 如何在 Webpack 中使用 Tree Shaking?

    我刚刚使用 Angular 2 版本 rc 2 应用程序 使用 Typescript 更新到 webpack 2 1 0 beta 15 但我想知道如何使用树摇动功能 我读到它应该 开箱即用 但我仍然有一个 1 7Mb 的捆绑包用于一个非常
  • 我在哪里可以下载 Facebook 的 PHP 源代码转换器 HipHop [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在哪里可以下载 PHP 版 HipH
  • 是否可以列出数据库中的所有外键?

    如何列出 sql server 数据库中的所有 F 我使用这个语句 看起来效果很好 SELECT RC CONSTRAINT NAME FK Name KF TABLE SCHEMA FK Schema KF TABLE NAME FK T
  • 带有电子邮件域的 AutoCompleteTextView android

    所以我的应用程序中有一个自动完成文本视图字段 我希望用户输入他的电子邮件地址 现在 为了帮助他更快地打字并且不犯错误 我想在打字时向他建议最常见的电子邮件域服务器 我将该控件与该数组一起使用 String arraymails gmail
  • 如何更改选项卡主机的默认颜色

    我使用的是2 2 SDK版本 我使用 TabHost 以选项卡视图格式显示活动 当我在手机中安装应用程序 版本2 2 1 时 选项卡主机颜色已更改为黄色 即使我也不给 TabHost 任何颜色 我不知道为什么颜色改变了 当我在模拟器中运行相
  • Android WebView UTF-8 不显示

    我有一个 webview 并尝试将简单的 UTF 8 文本加载到其中 mWebView loadData 將賦予他們的傳教工作標示為 text html UTF 8 但 WebView 显示 ANSI ASCII 垃圾 显然是编码问题 但是
  • Django 开发服务器重新加载时间太长

    自从我升级到 OSX Lion 以来 这一直是我的问题 每当我更改 Django 项目中的文件时 运行服务器重新加载 需要相当长的时间才能再次开始服务 即使在新创建的 Django 1 4 项目中也会发生这种情况 不过在 Snow Leop
  • 如何在 Python 2.7 中创建计时器?

    我目前正在使用 Pyglet 库编写一个打砖块克隆程序 我想制作一个计时器 为游戏的 奖励 即更长的桨 更快的桨移动 更大的球 计时长达 20 秒 我一直在尽我所能地在互联网上挖掘 但找不到答案 import threading bonus
  • 使用 Rails 中的表单批量更新对象

    我有一个人物模型和一个报价模型 每个人都可以有许多与其相关的引言 而这些引言又可以与作者 文本 网址等内容相关联 实际上 实际上只有一个人拥有引用对象 但所有人都可能拥有一个 我正在尝试在报价上使用一个非常简单的批量适度工具 例如 用户可以
  • 使用 Python 解析 SVG 文件路径

    我正在开发一个机器人项目 从 Android 运行设备拍摄一张照片 然后发送到 cloudconvert org 将其转换为 SVG 然后所有 SVG 路径将被转换为 x y 坐标并串行发送到机器人手臂 机器人手臂将绘制它们笔打开或关闭 所
  • Fancybox 3:单击图像时禁用缩放

    我使用 Fancybox 3 插件设置了一个简单的图像滑块 http fancyapps com fancybox 3 docs http fancyapps com fancybox 3 docs 在 Kirby CMS 中 https
  • R 中 0-1 之间的所有值组合总和为 1

    简单的问题 我试图获得 3 个数字 0 1 到 0 9 之间 的权重之和为 1 的所有组合 例子 c 0 20 0 20 0 60 c 0 35 0 15 0 50 权重相差 0 05 我已经尝试过这个 library gregmisc p
  • 在片段中使用上下文的最佳方式

    我在我的应用程序中使用片段 我创建了一个名为 BaseFragment 的父类 所有其他片段都扩展了此 Basefrgment 下面是此 Basefragment 的片段 基础片段 java public class BaseFragmen
  • 更新 Python Pickle 对象

    我正在做一个机器学习项目 为此我正在使用picklePython 的模块 基本上 我正在解析一个巨大的数据集 这在一次执行中是不可能的 这就是为什么我需要保存分类器对象并在下一次执行中更新它 所以我的问题是 当我使用新数据集再次运行程序时
  • 将观察结果与重叠日期相结合

    我的数据框中的每个观察结果都包含不同的 日期之前 和 日期之后实例 问题是每个 ID 的某些日期重叠 例如 在下表中 ID 1 和 4 包含重叠的日期值 ID before date after date 1 10 1 1996 12 1