查找与多个表的匹配项:使用 data.table 进行条件(完全)联接

2023-12-10

这可能有一个简单的解决方案,但我似乎无法破解它。

例如,假设我有一个列出购买和客户详细信息的表:

library(data.table)
purchase <- setDT(structure(list(Name = c("John", "John", "Mary"), Surname = c("Smith", 
"Smith", "Jane"), PurchaseDate = c("2017-01-01", "2015-01-01", 
"2017-01-02")), .Names = c("Name", "Surname", "PurchaseDate"), row.names = c(NA, 
-3L), class = c("data.table", "data.frame")))

> purchase
   Name Surname PurchaseDate
1: John   Smith   2017-01-01
2: John   Smith   2015-01-01
3: Mary    Jane   2017-01-02

我想知道这些客户在购买时是否持有有效的折扣卡,这与两个数据库中保存的数据相匹配:

df1 <- setDT(structure(list(Name = "John", Surname = "Smith", ValidFrom = "2016-12-31", 
    ValidTo = "2017-01-02"), .Names = c("Name", "Surname", "ValidFrom", 
"ValidTo"), row.names = c(NA, -1L), class = c("data.table", "data.frame")))

df2 <- setDT(structure(list(Name = "Mary", Surname = "Jane", ValidFrom = "2017-01-01", 
    ValidTo = "2017-01-03"), .Names = c("Name", "Surname", "ValidFrom", 
"ValidTo"), row.names = c(NA, -1L), class = c("data.table", "data.frame")))

> df1
   Name Surname  ValidFrom    ValidTo
1: John   Smith 2016-12-31 2017-01-02
> df2
   Name Surname  ValidFrom    ValidTo
1: Mary    Jane 2017-01-01 2017-01-03

我正在适应this解决方案,它使用data.table

library(data.table)
purchase[df1, on=c(Name='Name', Surname='Surname'), Match := 'Yes']
purchase[df2, on=c(Name='Name', Surname='Surname'), Match := 'Yes']

结果(基于左连接)保存到Match原来的变量purchase桌子。 (重要的是,这不需要创建新对象,而是将结果保存到原始对象中,否则会变得混乱。)

> purchase
   Name Surname PurchaseDate Match
1: John   Smith   2017-01-01   Yes
2: John   Smith   2015-01-01   Yes
3: Mary    Jane   2017-01-02   Yes

但是,我还需要检查PurchaseDate是在ValidFrom and ValidTo日期,并且不知道如何执行此操作。

为此,我可以引入ValidFrom and ValidTo加入日期,然后使用以下方法确定购买是否在这些日期之间ifelse.

purchase[df1, on=c(Name='Name', Surname='Surname'), `:=`(Match='Yes', VFrom=ValidFrom, VTo=ValidTo)]
purchase[df2, on=c(Name='Name', Surname='Surname'), `:=`(Match='Yes', VFrom=ValidFrom, VTo=ValidTo)]

伟大的!这带来了日期:

   Name Surname PurchaseDate Match      VFrom        VTo
1: John   Smith   2017-01-01   Yes 2016-12-31 2017-01-02
2: John   Smith   2015-01-01   Yes 2016-12-31 2017-01-02
3: Mary    Jane   2017-01-02   Yes 2017-01-01 2017-01-03

但是,如果客户有两张折扣卡,并且一次购买仅在其中一张折扣卡的有效期内,就会出现问题。假设玛丽有两张牌:

df2 <- setDT(structure(list(Name = structure(c(1L, 1L), .Label = "Mary", class = "factor"), 
    Surname = structure(c(1L, 1L), .Label = "Jane", class = "factor"), 
    ValidFrom = structure(1:2, .Label = c("2017-01-01", "1945-01-01"
    ), class = "factor"), ValidTo = structure(1:2, .Label = c("2017-01-03", 
    "1946-01-01"), class = "factor")), .Names = c("Name", "Surname", 
"ValidFrom", "ValidTo"), row.names = c(NA, -2L), class = c("data.table", "data.frame")))

> df2
   Name Surname  ValidFrom    ValidTo
1: Mary    Jane 2017-01-01 2017-01-03
2: Mary    Jane 1945-01-01 1946-01-01

运行这个

purchase[df2, on=c(Name='Name', Surname='Surname'), `:=`(Match='Yes', VFrom=ValidFrom, VTo=ValidTo)]

仅带来这些日期对之一(显然是最早的日期,无论行号如何)。

   Name Surname PurchaseDate Match      VFrom        VTo
1: John   Smith   2017-01-01   Yes 2016-12-31 2017-01-02
2: John   Smith   2015-01-01   Yes 2016-12-31 2017-01-02
3: Mary    Jane   2017-01-02   Yes 1945-01-01 1946-01-01

我如何引入所有匹配的行?

据我所知,X[Y]语法支持附加到原始对象(我需要),而且:=函数,我需要,但不支持完全连接。替代merge支持完全连接,但需要在每个连接步骤创建新对象(会非常混乱),并且不支持:=。有任何想法吗?有没有办法使用foverlaps不知何故?


这是一种处理方法:

# clean data
purchase[, PurchaseDate := as.IDate(PurchaseDate)]
df1[, `:=`(ValidFrom = as.IDate(ValidFrom), ValidTo = as.IDate(ValidTo))]
df2[, `:=`(ValidFrom = as.IDate(ValidFrom), ValidTo = as.IDate(ValidTo))]

# initialize
purchase[, matched := FALSE ]

# update joins
purchase[!(matched), matched := 
  df1[.SD, on=.(Name, Surname, ValidFrom <= PurchaseDate, ValidTo >= PurchaseDate), 
    .N, by=.EACHI ]$N > 0L
]
purchase[!(matched), matched := 
  df2[.SD, on=.(Name, Surname, ValidFrom <= PurchaseDate, ValidTo >= PurchaseDate), 
    .N, by=.EACHI ]$N > 0L
]

我保留着df1 and df2分开,因为OP提到它们的连接规则在实际用例中有所不同。


怎么运行的

整体结构是...

DT[, matched := FALSE ]
DT[!(matched), matched := expr1 ]
DT[!(matched), matched := expr2 ]

所以我们正在初始化matched为假;并在后面的每个步骤中更新不匹配的行,!(matched).

表达式开头为DT2[.SD, ...],这只是与我们过滤后的数据子集的连接!(matched)。像这样的连接查找行.SD in DT2根据on=过滤器。在这种情况下,on=过滤器与非等值连接相关联。***

当我们使用by=.EACHI我们按每一行分组.SD. With .N, by=.EACHI,我们得到的数量DT2与每行匹配的行.SD.

一旦我们有了匹配的行数,我们就可以比较N > 0L更新matched.


***不幸的是,截至 2017 年 4 月有一个未解决的错误在这种使用模式中有时会出现以下错误.SD。解决方法是更换.SD with copy(.SD).

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

查找与多个表的匹配项:使用 data.table 进行条件(完全)联接 的相关文章

  • randomForest 包在删除一个预测类时的奇怪行为

    我正在运行一个随机森林模型 它产生的结果从统计角度来看对我来说完全没有意义 因此我确信有些东西mustrandomForest 包的代码出现错误 至少在模型的本次迭代中 预测 左侧变量是具有 3 种可能结果的政党 ID 民主党 独立党 共和
  • 3 个表的 SQL 查询(或联接)

    第一次在 Stack Overflow 上问问题 很棒的资源 但是只有一件事真正让我作为 SQL 新手感到困惑 我有三个表 我想获取与鲍勃的学生相关的所有导师的姓名 表 1 教师 ID Name 1 Bob 表 2 学生 STUDENT I
  • 如何对数字进行四舍五入并使其显示零?

    R 中将数字四舍五入到小数点后 2 位的常用代码是 gt a 14 1234 gt round a digits 2 gt a gt 14 12 但是 如果该数字的前两位小数位为零 则 R 会在显示中抑制零 gt a 14 0034 gt
  • 使用 R 下载压缩数据文件、提取和导入数据

    EZGraphs 在 Twitter 上写道 很多在线 csv 都被压缩了 有没有办法下载 解压缩存档并使用 R 将数据加载到 data frame Rstats 我今天也尝试这样做 但最终只是手动下载 zip 文件 我尝试过类似的东西 f
  • R中的重叠矩阵

    我有以下数据框 id channel 1 a 1 b 1 c 2 a 2 c 3 a 我想创建并重叠矩阵 它基本上是一个方阵 行和列标签为 a b c 表中的每个条目显示每个通道共有多少个 id 例如 在上面的例子中 矩阵看起来像 a b
  • 在R中循环子文件夹

    我正在 R 环境中包含多个子文件夹的文件夹中工作 我想要循环遍历多个子文件夹 然后在每个子文件夹中调用 R 脚本来执行 我想出了下面的代码 但我的代码似乎添加了 到子文件夹列表 我收到错误 文件中的错误 文件名 r 编码 编码 无效的 描述
  • 实现 XGboost 自定义目标函数

    我正在尝试使用 XGboost 实现自定义目标函数 在 R 中 但我也使用 python 所以有关 python 的任何反馈也很好 我创建了一个返回梯度和粗麻布的函数 它工作正常 但是当我尝试运行 xgb train 时它不起作用 然后 我
  • 如何按时间间隔匹配数据帧?

    这是我从数据记录器导入原始数据时经常出现的问题 温度记录仪设置为每十分钟记录一次温度 单独的气体记录仪设置为记录最后十分钟间隔内使用的气体 我想将这两个记录器的数据合并到一个数据框中进行绘图和分析 但时间并不完全一致 我希望每十分钟的时间段
  • 绘制 Cox 回归的 Kaplan-Meier 图

    我使用 R 中的以下代码设置了一个 Cox 比例风险模型来预测死亡率 添加协变量 A B 和 C 只是为了避免混淆 即年龄 性别 种族 但我们真正对预测变量 X 感兴趣 X 是一个连续变量 cox model lt coxph Surv t
  • 如何按用户定义(例如非字母顺序)对数据框进行排序[重复]

    这个问题在这里已经有答案了 给定一个数据框dna gt dna chrom start chr2 39482 chr1 203918 chr1 198282 chrX 7839028 chr17 3874 以下代码重新排序dna by ch
  • 如何在 R 中执行近似(模糊)名称匹配

    我有一个专门用于生物学期刊的大型数据集 该数据集是由不同的人长时间编写的 因此 数据不采用单一格式 例如 在 作者 栏中我可以找到John Smith Smith John Smith J等 但它们是同一个人 我连最简单的动作都做不了 例如
  • 将列表中的每个元素转换为数据框中的一列

    假设我有以下列表 d library combinat d permn c a b c 这看起来如下 1 1 a b c 2 1 a c b 3 1 c a b 4 1 c b a 5 1 b c a 6 1 b a c 是否可以将此列表的
  • 多个动态滤镜更新闪亮

    我希望能够让 UI 输入闪亮 并根据用户之前的选择进行自我更新 因此 在下面的示例中 预期的行为是用户选择cyl vsor carb那么这将 过滤数据集mtcars用于创建绘图 即用户根据过滤条件调整绘图并 更新其他过滤器中的剩余输入选择
  • 在 Select(DropDown) 更改事件上重新初始化 Jquery DataTable

    我正在使用 Jquery UI DataTable 它被填充select DropDown change事件 在PageLoad没关系 当我表演时dropdown change event DataTable is Reinitialize
  • R - 重塑 - 熔化错误

    我正在尝试融化数据框 但出现了这个奇怪的错误 有什么想法吗 str zx7 data frame 519 obs of 5 variables calday new Date format 2011 01 03 2011 01 04 201
  • 从 data.frame 在 ggplot 图例中添加信息

    我想在图例中添加信息 哪个传感器具有该值 这是我的代码 z lt data frame a c sensor 1 sensor 2 sensor 3 sensor 4 sensor 5 sensor 6 sensor 7 sensor 8
  • 在 RMarkdown 输出到 PDF 时缩进而不添加项目符号点或编号

    之前有人问过如何在没有项目符号的情况下缩进文本 RMarkdown 中的点 但这是针对 HTML 输出的 在 RMarkdown 中缩进而不添加项目符号点或数字 https stackoverflow com questions 47087
  • 在网格中制作一个矩形图例,并标记行和列

    我有一个 ggplot 我将因子映射到填充和 alpha 如下所示 set seed 47 the data lt data frame value rpois 6 lambda 20 cat1 rep c A B each 3 cat2
  • R:按组,测试一个变量的每个值是否存在于另一个变量中

    我有一个数据框架 结构如下 a lt c 1 1 1 2 2 2 3 3 3 3 4 4 b lt c 1 2 3 1 2 3 1 2 3 4 1 2 c lt c NA NA 2 NA 1 1 NA NA 1 1 NA NA df lt
  • 从数据框中绘制多条平滑线

    我对 R 比较陌生 我正在尝试绘制从 csv 文件加载的数据框 数据由 6 列组成 如下所示 xval col1 col2 col3 col4 col5 第一列 xval 由一系列单调递增的正整数 例如 10 40 60 等 组成 其他列

随机推荐

  • ObjectListView 强制转换异常(用于命中测试)

    我正在使用 Grammarian 的 ObjectListView 我将旧的列表视图更改为该视图 但我所做的只是填写项目 但是当应用程序启动并且我的鼠标位于列表视图上时 它立即抛出异常 System InvalidCastException
  • 在 SearchView 中放置进度微调器?

    我在我的 Activity 中使用 SearchView 当用户键入时 我正在向服务器执行搜索请求 我想表明一些活动正在发生 是否可以在 SearchView 中显示进度微调器 否则 人们如何处理这个问题 我们是否创建一个自定义操作栏父布局
  • python 右对齐

    我如何证明这段代码的输出是合理的 N int input case print case for i in range N case print case 您可以使用format with gt 右对齐 N 10 for i in rang
  • 非默认版本的 appspot.com 子域上的 SSL

    我想在我的 GAE 应用程序的非默认版本上使用 SSL 对于正常的https my app appspot com我知道我什么都不用做 不过我有另一个版本 该版本位于https v2 my app appspot comSSL 不起作用 它
  • 以正确的 1:1 比例在圆形边框中制作 Font Awesome 图标

    在某些情况下 如果图标的比例不是 1 1 则边框不再是圆形 这是一个例子 我目前正在使用 HTML socials a href i class fa fa facebook i a href i class fa fa twitter i
  • Javascript - 如何将原始对象传递给回调函数

    我遇到的问题专门针对 D3 js 但我之前也遇到过类似的问题 并且最终总是使用 hack 来解决它 我有一个包含对象数组的类 有一个功能可以从 CSV 文件添加新对象 使用d3 csv 该函数采用一个文件名和一个带有一个参数的回调函数 cs
  • 二叉树 - 取消引用指针[关闭]

    Closed 这个问题是无关 目前不接受答案 我只是想编写一个简单的二叉搜索树程序 用户可以在其中插入节点并以中序 前序或后序模式查看树中的所有节点 我的代码是 include
  • MySQL FIND_IN_SET 或等效项可以使用索引吗?

    如果我比较 explain select from Foo where find in set id 2 3 id select type table type possible keys key key len ref rows Extr
  • 使用 C++ 的 CPU ID - windows

    我想使用 C 获取我的计算机 Windows 的 CPU Id I used 这段代码为拿到它 为实现它 它输出类似的信息 For InfoType 0 CPUInfo 0 0x5 CPUInfo 1 0x756e6547 CPUInfo
  • 装箱/拆箱和类型转换有什么区别?

    装箱 拆箱和类型转换有什么区别 通常 这些术语似乎可以互换使用 装箱是指将不可空值类型转换为引用类型或将值类型转换为其实现的某个接口 例如int to IComparable
  • Node.js MongoDB collection.find().toArray 不返回任何内容[重复]

    这个问题在这里已经有答案了 虽然我发现了与我类似的问题 但我无法自己解决问题 在我的 models user 模型中 我想找到所有用户并将它们放入数组中 然后将该数组返回到控制器 我将在其中使用信息 这是我的代码 var mongoData
  • 在 React Native 中从 Firebase 数据库/存储加载并返回图像

    我有一个 Firebase 应用程序设置 其中包含实时数据库中的一系列项目 每个项目都有一个imagePath节点 包含 Firebase 存储 URI 例如 gs bucket images stars jpg 项目数组用于
  • JPanel 上的 KeyListener 随机无响应

    我的项目中的默认 Java KeyListener 遇到问题 我注意到 当我启动时 KeyListener 有时似乎没有转发 KeyEvents 问题症状 启动应用程序时 不处理按键输入 这只是有时发生 有时我必须关闭并启动应用程序 7 8
  • 如何使用 Javascript 动态更改缩放级别?

    我正在尝试找出如何重置 ios 网页中的缩放级别 似乎当用户进行捏放大 缩小时 缩放功能不再起作用 我想要捏合手势 但想以编程方式重置缩放 有人有关于使用 Javascript jQuery 动态改变缩放的想法吗 document read
  • Jenkins 在 Linux 或 Windows 上运行 Maven 构建

    我有一个 Java 应用程序的 Maven 构建 通过键入相同的命令可以在 Linux 或 Windows 上成功运行mvn install 然而 使用Jenkinsfile方法设置此版本时 在 Linux 上该文件需要包含sh mvn i
  • Appcelerator 和 CommonJS 模块(缓存和循环引用)

    事情是这样的 我正在使用 CommonJS 方式使我的移动 iPhone Android 应用程序模块化 这并不奇怪 但有一件事我就是无法理解 CommonJS 允许我创建 STATIC 私有变量 这让我可以轻松创建单例 我认为至少这是因为
  • 将数组传递给函数:数组必须具有“Sized”类型

    我构建了一个像这样的数组的数组 let mut my array false WIDTH HEIGHT where WIDTH and HEIGHT是先前定义的常量 我想将整个数组传递给函数 并更改数组中的值 尽管不是数组的大小 长度 我试
  • 使用 spring-test-mvc jsonpath 测试返回 null

    我正在使用 Spring 的 spring test mvc 库来测试 Web 控制器 我有一个非常简单的控制器 它返回一个 JSON 数组 然后在我的测试中我有 Test public void shouldGetAllUsersAsJs
  • PySpark 当列表中的项目时

    以下是我想要实现的操作 types 200 300 def Count ID cnd F when F col type in types 1 otherwise F lit 0 return F sum cnd alias CountTy
  • 查找与多个表的匹配项:使用 data.table 进行条件(完全)联接

    这可能有一个简单的解决方案 但我似乎无法破解它 例如 假设我有一个列出购买和客户详细信息的表 library data table purchase lt setDT structure list Name c John John Mary