【问题标题】:Merge based on 2 columns values - Check for duplicate key values error基于 2 列值合并 - 检查重复键值错误
【发布时间】:2015-04-14 20:14:12
【问题描述】:

我有两个包含以下列的数据表 - ddate,fnumber,file,modelfnumber,ddate,model,model_id,file。我想用与ddatefnumber 列匹配的第二个表中的值更新第一个表。

如果我使用merge:

dtPT <- merge(dtPT, dtAT, by = c("fnumber", "ddate"), all.x = TRUE)

然后我收到以下错误 -

vecseq 中的错误(f__, len__, if (allow.cartesian || notjoin) NULL else as.integer(max(nrow(x), : Join 结果为 8568291 行;多于 8537179 = 最大值(nrow(x),nrow(i))。检查 i 中的重复键值, 每个都一遍又一遍地加入 x 中的同一组。如果 没关系,尝试包括 j 并删除 by (by-without-by) 以便 j 为每个组运行以避免大量分配。如果你确定 如果您希望继续,请使用 allow.cartesian=TRUE 重新运行。除此以外, 请在 FAQ、Wiki、Stack Overflow 中搜索此错误消息 和 datatable-help 寻求建议。

我尝试在dtAT中搜索重复记录:

setkeyv(dtAT, c("fnumber", "ddate"))
dtAT[duplicated(dtAT)]

但它返回 0 行。

我也尝试改用match,但它并没有像我预期的那样工作(下面使用示例数据):

tPT <- "ddate,fnumber,file,model
2014-05-26,S71149,ps1.csv,320
2014-09-26,,ps2.csv,
2014-10-16,,ps3.csv," 

tAT <- 
"fnumber,ddate,model,model_id,file
S71149,2014-05-26,319,VU-BHP,as1.csv
S71149,2014-05-25,320,,as2.csv
S71149,2014-05-23,322,VU-BTP,as3.csv"

columnClasses <- c("POSIXct", "factor", "character", "factor")
dtPT <- read.csv(text=tPT, header = TRUE, sep = ",", na.strings = c(""), colClasses = columnClasses)
dtPT <- as.data.table(dtPT)

columnClasses <- c("character", "POSIXct", "character", "factor", "factor")
dtAT <- read.csv(text=tAT, header = TRUE, sep = ",", na.strings = c(""), colClasses = columnClasses)
dtAT <- as.data.table(dtAT)

dtPT$model_code <- dtAT[match(paste(dtAT$fnumber, dtAT$ddate), paste(dtPT$fnumber, dtPT$ddate)), dtAT$model] 

结果中的上述代码将model_code 值分配给所有行:

        ddate fnumber    file model model_code
1: 2014-05-26  S71149 ps1.csv   320        319
2: 2014-09-26      NA ps2.csv    NA        320
3: 2014-10-16      NA ps3.csv    NA        322

320 应该只分配给第一行时:

        ddate fnumber    file model model_code
1: 2014-05-26  S71149 ps1.csv   320        319
2: 2014-09-26      NA ps2.csv    NA         NA
3: 2014-10-16      NA ps3.csv    NA         NA

因为对于第二行和第三行,ddatefnumber 的组合不匹配。

merge 当然可以很好地与下面的示例配合使用,但会返回带有生产数据的错误)

【问题讨论】:

  • 您的键列中有 值吗?也许它们会引起问题
  • 你的 data.table 版本是多少?在1.9.5 中修复了一些极端情况,以确保仅当i 有重复时才会发生错误。我建议尝试使用1.9.5,如果您仍然收到错误,那么您肯定在i 中有重复项。如果您也确定并且想要继续,请按照错误消息告诉您的设置 allow.cartesian=TRUE
  • @Arun,data.table 版本是 1.9.4
  • @Floo0,没有NA
  • 我认为dtAT[duplicated(dtT)] 中缺少字母“A”?

标签: r merge data.table


【解决方案1】:

我想用第二个表中的值更新第一个表

在 data.table 中有一个 update on join 功能,而不是 merge 函数,它会更快,因为它通过引用更新并且不需要在连接后实现更大的数据集。 一般语法是

DT1[DT2, value := i.lookup_value]

那么去你的例子

library(data.table)

tPT <- "ddate,fnumber,file,model
2014-05-26,S71149,ps1.csv,320
2014-09-26,,ps2.csv,
2014-10-16,,ps3.csv," 

tAT <- "fnumber,ddate,model,model_id,file
S71149,2014-05-26,319,VU-BHP,as1.csv
S71149,2014-05-25,320,,as2.csv
S71149,2014-05-23,322,VU-BTP,as3.csv"

columnClasses <- c("POSIXct", "factor", "character", "factor")
dtPT <- read.csv(text=tPT, header = TRUE, sep = ",", na.strings = c(""), colClasses = columnClasses)
dtPT <- as.data.table(dtPT)

columnClasses <- c("character", "POSIXct", "character", "factor", "factor")
dtAT <- read.csv(text=tAT, header = TRUE, sep = ",", na.strings = c(""), colClasses = columnClasses)
dtAT <- as.data.table(dtAT)

setkeyv(dtPT, c("fnumber","ddate"))
setkeyv(dtAT, c("fnumber","ddate"))

dtPT[dtAT, model_code := i.model]
#         ddate fnumber    file model model_code
# 1: 2014-09-26      NA ps2.csv    NA         NA
# 2: 2014-10-16      NA ps3.csv    NA         NA
# 3: 2014-05-26  S71149 ps1.csv   320        319

如果您收到提到的错误,您应该首先检查重复项,但不是检查整行,而是检查复合键。下面是简单的代码。

dtPT[,.N,c("fnumber","ddate")][N>1L]
dtAT[,.N,c("fnumber","ddate")][N>1L]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 2016-04-26
    • 2013-04-10
    • 1970-01-01
    • 2021-12-02
    • 2018-12-29
    • 2021-01-10
    相关资源
    最近更新 更多