带有R中条件的内连接

Posted

技术标签:

【中文标题】带有R中条件的内连接【英文标题】:Inner Join with conditions in R 【发布时间】:2015-09-19 16:50:13 【问题描述】:

我想做内部连接,条件是它应该给我减去 2 列。

df1 = data.frame(Term = c("T1","T2","T3"), Sec = c("s1","s2","s3"), Value =c(10,30,30))

df2 = data.frame(Term = c("T1","T2","T3"), Sec = c("s1","s3","s2"), Value =c(40,20,10)

 df1
 Term Sec Value
  T1  s1    10
  T2  s2    30
  T3  s3    30

  df2
  Term  Sec Value
  T1  s1    40
  T2  s3    20
  T3  s2    10

我想要的结果是

  Term  Sec Value
   T1   s1   30
   T2   s2   20
   T3   s3   10

基本上我要加入两个表,对于我要使用的列值

Value=  abs(df1$Value - df2$Value)

我一直在努力,但找不到任何方法在基础 R 中执行此条件合并。可能如果基础 R 不可能,dplyr 应该能够使用 inner_join() 做到这一点,但我不太清楚这个包。

因此,任何关于 base R 和/或 dplyr 的建议都将不胜感激

编辑

我已按要求包含了我的原始数据。我的数据在这里

https://jsfiddle.net/6z6smk80/1/

DF1 是第一个表,DF2 是第二个。 DF2 从第 168 行开始。

所有逻辑相同,我想加入这两个长度为 160 行的表。我想通过 ID 加入并从两个表中获取列值的差异。结果数据集应具有相同的行数,即 160 行,并带有额外的列差异

【问题讨论】:

不清楚您是如何加入表格的。如果它在单列上,您可以使用with(merge(df1, df2, by = "Sec"), abs(Value.x - Value.y) 不幸的是,他的样本数据集并没有让我们真正看到它是什么类型的连接。 【参考方案1】:

使用data.tables 二进制连接,您可以在连接时修改列。 nomatch = 0L 确保您正在进行内部连接

library(data.table)
setkey(setDT(df2), Sec)
setkey(setDT(df1), Sec)[df2, .(Term, Sec, Value = abs(Value - i.Value)), nomatch = 0L]
#    Term Sec Value
# 1:   T1  s1    30
# 2:   T2  s2    20
# 3:   T3  s3    10

【讨论】:

你看到了一些我没有看到的东西。请详细说明。 @TimBiegeleisen Ops 第二行所需的输出是:T2 s2 20。你的是T2 s2 10。你没看到吗?第三排也是一样。 所以我最初加入Sec 列是对的。 您应该只通过Sec 加入,是的。【参考方案2】:

这是一个“基本 R”解决方案,使用 Term 列上的 merge() 函数,由原始 df1df2 数据框共享:

df_merged <- merge(df1, df2, by="Sec")
df_merged$Value <- abs(df_merged$Value.x - df_merged$Value.y)
df_merged <- df_merged[, c("Sec", "Term.x", "Value")]
names(df_merged)[2] <- "Term"

> df_merged
  Sec Term Value
1  s1   T1    30
2  s2   T2    20
3  s3   T3    10

【讨论】:

@user3050590 请查看给出的答案,谢谢。 如果 Sec 是分类变量怎么办? @user3050590 在我上面给出的代码中,Sec 列是一个因素。我还将Sec 列更改为character,它也有效。 当我使用我的实际数据集运行它时,在合并之后,它会在合并表中创建 6400 个条目。最初在我的两个表中,每个表都有 160 个条目。因此,我没有得到预期的结果:( 您的数据集有问题。你能用更大的样本更新你的 OP 吗?我认为这里给出的 3 个答案中的任何一个都应该可以正常工作。其他回复是否也为您提供了 6400 个条目?【参考方案3】:

由于这是一个 dplyr 问题,这里是一个 dplyr 解决方案:

首先使用inner_join,然后使用transmute 来保留变量并计算和追加一个新变量。

inner_join(df1, df2, by = "Sec") %>% 
  transmute(Term = Term.x, Sec, Value = abs(Value.x - Value.y))

【讨论】:

如果 Sec 是分类变量怎么办?

以上是关于带有R中条件的内连接的主要内容,如果未能解决你的问题,请参考以下文章

带有熊猫数据框的内连接循环,用于可能存在或不存在的各种组合[重复]

带 MAX 函数的内连接 - SQL SERVER-

MySQL数据库,内连接外连接中做条件筛选和WHERE中条件筛选的区别

OR 连接查询注意

有啥方法可以计算 Redshift 中条件的运行总计?

Redshift - 提取匹配数组中条件的值