在两个数据表(dt1,dt2)上进行左外连接的最简单方法是使用填充值为0(或其他某个值)而不是NA(默认值)而不覆盖左数据表中的有效NA值?
一个常见的答案,例如在这个线程中,使用dplyr::left_join或者data.table::merge或者用data.tabledt2 [dt1]键控列括号语法进行左外连接,接着是第二步,简单地用连接数据表替换所有NA值0.例如:
library(data.table);
dt1 <- data.table(x=c('a', 'b', 'c', 'd', 'e'), y=c(NA, 'w', NA, 'y', 'z'));
dt2 <- data.table(x=c('a', 'b', 'c'), new_col=c(1,2,3));
setkey(dt1, x);
setkey(dt2, x);
merged_tables <- dt2[dt1];
merged_tables[is.na(merged_tables)] <- 0;
Run Code Online (Sandbox Code Playgroud)
这种方法必然假定没有有效的NA值dt1需要保留.然而,正如您在上面的示例中所看到的,结果是:
x new_col y
1: a 1 0
2: b 2 w
3: c 3 0
4: d 0 y
5: e 0 z
Run Code Online (Sandbox Code Playgroud)
但是期望的结果是:
x new_col y
1: a 1 NA
2: b …Run Code Online (Sandbox Code Playgroud) 简介:我想通过共享id密钥将两个表合并为all=true(完全外部联接),而不是将具有相同名称的列设置为var1.x var2.y等,它们将合并为单个列,其中左表中缺少(NA)值由右表中的值填充(除了合并的标准行为,即附加具有不同ID的行和具有不同名称的列).
细节:
我想基于共享密钥列合并+更新table1,以便:table2id
1)如果table1并且table2具有相同名称(除了id)之外的列,则如果值table1存在,则保留为单独的值,table2如果值为table1NA ,则将值替换为值in .
2)如果table2具有table1没有(不同名称)的列,则它们被合并(通过id).
3)如果table1具有id不匹配的table2,则不同名称列的值为table2NA
4)如果table2有一个id不匹配的table1,则将其添加为新行,并且不同列名的值为table1NA.
3和4是与标准merge带all=TRUE.
我担心我已经推翻了这个问题,因为我无法找到一个简单的方法来执行此操作,merge或者join不涉及ifelse在每个列上创建检查.真实数据有大约1000列,因此ifelse对每个列进行查找都是非常长的解决方案.
可重复的简化示例:
table1 <- data.table(id =c("id1", "id2", "id3", "id4", "id5", "id6"),
var1=c(1,2,3,4,5, 6),
var2=c("a", "b", NA, "d", NA, …Run Code Online (Sandbox Code Playgroud) 在大型数据集(约1M个案例)中,每个案例都有一个"已创建"和一个"审查" dateTime.我想计算每个案例创建时打开的其他案例的数量.案件在他们的"创造"和"审查"之间开放dataTimes.
有几种解决方案适用于小型数据集(<100,000个案例),但计算时间呈指数增长.我的估计是计算时间增加为函数3n ^ 2.在n = 100,000的情况下,我的服务器上的计算时间大于20分钟,具有6*4GHz内核和64GB RAM.即使使用多核库,充其量也可以将时间减少8或10倍.不足以处理大约1M的情况.
我正在寻找一种更有效的方法来进行这种计算.下面我提供了一个函数,允许您轻松创建大量"创建"和"删失" dateTime对以及目前为止尝试的两个解决方案,使用dplyr和data.table库.为简单起见,将时间报告给用户.您只需更改顶部的"CASE_COUNT"变量即可重新执行并再次查看时间,并轻松比较您可能需要建议的其他解决方案的时间.
我将使用其他解决方案更新原始帖子,以便给予作者适当的信任.在此先感谢您的帮助!
# Load libraries used in this example
library(dplyr);
library(data.table);
# Not on CRAN. See: http://bioconductor.org/packages/release/bioc/html/IRanges.html
library(IRanges);
# Set seed for reproducibility
set.seed(123)
# Set number of cases & date range variables
CASE_COUNT <<- 1000;
RANGE_START <- as.POSIXct("2000-01-01 00:00:00",
format="%Y-%m-%d %H:%M:%S",
tz="UTC", origin="1970-01-01");
RANGE_END <- as.POSIXct("2012-01-01 00:00:00",
format="%Y-%m-%d %H:%M:%S",
tz="UTC", origin="1970-01-01");
# Select which solutions you want to run in this test …Run Code Online (Sandbox Code Playgroud) 我正在尝试找到一种更有效的方法来计算每个案例创建时间开放的案例数.案件在其创建日期/时间戳与其审查日期/时间戳之间是"开放的".您可以复制粘贴下面的代码来查看一个简单的功能示例:
# Create a bunch of date/time stamps for our example
two_thousand <- as.POSIXct("2000-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_one <- as.POSIXct("2001-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_two <- as.POSIXct("2002-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_three <- as.POSIXct("2003-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_four <- as.POSIXct("2004-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_five <- as.POSIXct("2005-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_six <- as.POSIXct("2006-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_seven <- as.POSIXct("2007-01-01 00:00:00", format="%Y-%m-%d %H:%M:%S", tz="UTC", origin="1970-01-01");
two_thousand_eight <- as.POSIXct("2008-01-01 00:00:00", format="%Y-%m-%d …Run Code Online (Sandbox Code Playgroud)