【问题标题】:Joining two dataframes with sqldf results in NA Column使用 sqldf 连接两个数据框会导致 NA 列
【发布时间】:2015-11-02 13:50:18
【问题描述】:

我正在尝试使用 sqldf 包连接两个数据框。

这些是我的两个数据框的可重现示例:

a <- c(1,2,3,4,5)
b <- c(1,2,3,4,5)
c <- c(1,2,3,4,5)
d <- c(1,2,3,4,5)
e <- c(1,2,3,4,5)

dataframe1 <- data.frame(a,b,c,d,e)

a <- c(NA,NA,NA,NA,5)
b <- c(NA,NA,NA,4,NA)
c <- c(NA,NA,3,NA,NA)
d <- c(NA,2,NA,NA,NA)
e <- c(1,NA,NA,NA,NA)
f <- c(1,2,3,4,5)

dataframe2 <- data.frame(a,b,c,d,e,f)

这是数据帧连接的可重现示例:

final_data <- sqldf("SELECT *
                     FROM dataframe1
                     LEFT OUTER JOIN dataframe2 USING(a,b,c,d,e)")

通过连接引入的 final_data 中的结果 f 列用 NA 填充。为什么?理想的 f 列将具有 dataframe2 中存在的 a、b、c、d 和 e 的相应值。我该如何解决这个问题?

【问题讨论】:

  • 两个数据框之间没有匹配的行,所以结果是dataframe1,在新的f 列中具有所有NULL(SQL 中的NULL,R 中的NA)值.如果您想要 f 列中的值,您至少需要一行,其中所有 a, b, c, d, e 在数据帧之间匹配。
  • 有没有办法在我的联接中排除 NA,只在 dataframe2 的每一行中插入与共享值对应的值? R 中的 merge() 函数使用参数“incompatibles = NA”来执行此操作,但这仅在加入一列并且我加入 5 时才有效。
  • 也许我可以在我的连接中指定在 (a OR b OR c OR d OR e) 上加入公共列,以便它仅在匹配其中一个值时加入。我怎么能把它放在 sql 中?
  • 或者自定义函数来完成这项工作?

标签: sql r join


【解决方案1】:

如果要OR条件,对应的SQL是

SELECT *
FROM dataframe1 d1
LEFT OUTER JOIN dataframe2 d2
ON (
  d1.a = d2.a
  OR d1.b = d2.b
  OR d1.c = d2.c
  OR d1.d = d2.d
  OR d1.e = d2.e
)

由于来自df1 的列值不一定等于来自df2 的列值,因此您可以从它们中的每一个中获取一个副本。如果您只想保留来自df1 的值以及来自df2f 的值,请执行以下操作:

SELECT d1.*, d2.f
FROM dataframe1 d1
LEFT OUTER JOIN dataframe2 d2
ON (
  d1.a = d2.a
  OR d1.b = d2.b
  OR d1.c = d2.c
  OR d1.d = d2.d
  OR d1.e = d2.e
)

我所知道的 R 连接函数(mergeplyr::joindplyr::left_join)都要求连接中的所有列都相等,尽管您可以很容易地组合一个自定义函数来连接一个一次,然后coalesces 结果。

【讨论】:

  • 这行得通。谢谢格雷戈尔。我不知道库完全接受原生 sql。
  • 它实际上创建了一个 SQL 数据库,导入您使用的任何数据帧,执行您的 SQL,并将结果导出回 R。
  • 有趣 - 这是一个不同的问题,但你知道是否有任何 r 包可以将数据帧作为表导入到 sql 数据库中?
  • RODBC 是一个很好的,也有很多 DB 特定的包。在“反向依赖”列表of the DBI package 中查看几乎所有内容。许多“反向导入”也是如此。
  • 使用 sqldf 将 BOD data.frame 存储在 mydb 数据库中(如果数据库不存在则创建数据库):sqldf(c("attach mydb as new", "create table new.BOD as select * from BOD")) ;然而,通常人们会为此直接使用 RSQLite 包。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 2015-02-03
  • 2019-01-05
  • 1970-01-01
  • 2022-01-11
  • 2015-07-08
相关资源
最近更新 更多