r - R - 删除 data.table 滚动连接中所有不匹配行的最有效方法(而不是半连接的两步过程)
问题描述
目前通过解决方法解决此问题,但我想知道是否有更有效的方法。
有关示例性数据,请参见下文:
library(data.table)
library(anytime)
library(tidyverse)
library(dplyr)
library(batchtools)
# Lookup table
Date <- c("1990-03-31", "1990-06-30", "1990-09-30", "1990-12-31",
"1991-03-31", "1991-06-30", "1991-09-30", "1991-12-31")
period <- c(1:8)
metric_1 <- rep(c(2000, 3500, 4000, 100000), 2)
metric_2 <- rep(c(200, 350, 400, 10000), 2)
id <- 22
dt <- setDT(data.frame(Date, period, id, metric_1, metric_2))
# Fill and match table 2
Date_2 <- c("1990-08-30", "1990-02-28", "1991-07-31", "1991-09-30", "1991-10-31")
random <- c(10:14)
id_2 <- c(22,33,57,73,999)
dt_fill <- setDT(data.frame(EXCL_DATE, random, id_2))
# Convert date columns to type date
dt[ , Date := anydate(Date)]
dt_fill[ , Date_2 := anydate(Date_2)]
现在进行数据争论。dt
我想从(又名查找表)中获取最新的先前数据到dt_fill
. 我用这样一个简单的 1 线滚动连接来做到这一点。
# Rolling join
dt_res <- dt[dt_fill, on = .(id = id_2, Date = Date_2), roll = TRUE]
# if not all id_2 present in id column in table 1, we get rows with NA
# I want to only retain the rows with id's that were originally in the lookup table
然后我以一堆填充了NAs
我想删除的新添加列的行结束。我用semi-join
. 我发现过时的解决方案很难理解,并解决了batchtools::sjoin()
本质上也是单线的功能。
dt_final <- sjoin(dt_res, dt, by = "id")
有没有比先进行滚动连接然后与原始数据集进行半连接更有效的方法来完成滚动连接的干净输出结果。对于非常长的数据集,它也不是很快。谢谢!
解决方案
从本质上讲,我发现有两种方法都是可行的解决方案。
解决方案 1
首先,由 lil_barnacle 提出的是一个优雅的单行代码,如下所示:
# Rolling join with nomtach-argument set to 0
dt_res <- dt[dt_fill, on = .(id = id_2, Date = Date_2), roll = TRUE, nomatch=0]
原始方法
像这样添加nomatch
参数并将其设置为 0 nomatch = 0
,相当于先进行滚动连接,然后再进行半连接。
# Rolling join without specified nomatch argument
dt_res <- dt[dt_fill, on = .(id = id_2, Date = Date_2), roll = TRUE]
# Semi-join required
dt_final <- sjoin(dt_res, dt, by = "id")
解决方案 2
其次,我想出的解决方案是在滚动连接之前通过“连接变量”过滤来“对齐”两个数据集,如下所示:
# Aligning data sets by filtering accd. to joined 'variable'
dt_fill <- dt_fill[id_2 %in% dt[ , unique(id)]]
# Rolling join without need to specify nomatch argument
dt_res <- dt[dt_fill, on = .(id = id_2, Date = Date_2), roll = TRUE]
推荐阅读
- bash - 如何直接在 bash 脚本中运行 PowerShell 核心命令?
- flutter - Flutter & Firebase:如何验证 isNewUser Firebase 并显示 WelcomeScreen Flutter?
- awk - 使用管道和字数(wc)然后修饰结果
- conda - 尝试加载 r-seurat 时出现 UnsatisfiableError
- javascript - 创建图表时未按预期返回数据
- go - 测试时Golang“插件是用不同版本的包构建的”
- python - 展平 JSON / 字典 / 列表
- graphics - Phong 着色和 Gouraud 着色有什么区别?
- maven - 生成标准 Maven 插件文档
- acumatica - acumatica 形式的 IFRAME