【问题标题】:R: unequi join with merge functionR:具有合并功能的不等连接
【发布时间】:2021-04-20 07:25:05
【问题描述】:

我正在与 data.table 合作,我想做一个非 equi 左连接/合并。

我有一张汽车价格表和另一张表来确定每辆车所属的汽车类别:

data_priceclass <- data.table()
data_priceclass$price_from <- c(0, 0, 200000, 250000, 300000, 350000, 425000, 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000) 
data_priceclass$price_to <- c(199999, 199999, 249999, 299999, 349999, 424999, 499999, 599999, 699999, 799999, 899999, 999999, 1099999, 1199999, 1299999, 1399999, 1499999, 1599999, 1699999, 1799999, 1899999)
data_priceclass$price_class <- c(1:20, 99)

我使用非 equi 连接来合并两个表。但是data.table 的 x[y]-join 语法会删除重复项。

cars <- data.table(car_price = c(190000, 500000))
cars[data_priceclass, on = c("car_price >= price_from", 
                             "car_price < price_to"),
     price_class := i.price_class,]
cars

请注意,值为 190000 的汽车应该在 data_priceclass 表中的两行上得到匹配,但由于 x[y] 删除了重复项,因此我在输出中看不到这一点。通常,当我加入时,我总是使用merge 函数而不是 x[y],因为我在使用 x[y] 时会失去控制。

但以下内容不适用于非 equi 连接:

merge(cars, data_priceclass,
      by = c("car_price >= price_from", 
             "car_price < price_to"),
      all.x = T , all.y = F)

任何提示我如何使用不删除重复项的 data.table 进行非 equi 连接?

【问题讨论】:

  • x[y] 不会删除重复项。这是因为您使用的是 := ,它会查找表 x。
  • @chinsoon12 实际上有点像,但我同意你的观点
  • 虽然没有解决我的问题
  • 试试 data_priceclass[cars, on=.(car_price>=price_from, car_price
  • 我认为@chinsoon12 的意思是尝试data_priceclass[cars, on = .(price_from &lt;= car_price, price_to &gt; car_price)]。您在尝试中没有得到重复的原因是因为 car 数据只有两行,而您尝试使用 := 分配 3 行。因此,您需要增加car 的大小,而不能增加:=。使用data_priceclass[cars] 而不是cars[data_priceclass] 的原因是因为X[Y] 这意味着“为Y 中的每个值找到X 中的所有匹配记录” 在你的情况下,你想找到所有data_priceclass 中的值对应cars 中的每个值。

标签: r data.table non-equi-join


【解决方案1】:

如 cmets 中所述,cars 上的左连接是通过在 DT[i,j,by] 语法中使用 cars 作为子集条件 i 来完成的。
这将cars 放在右侧,与SQL 相比,这可能违反直觉,我发现tutorial 对比较两种语法很有用。

cars <- data.table(car_price = c(190000, 500000))
data_priceclass[cars, .(car_price,x.price_from,x.price_to,price_class),on = .(price_from <= car_price,price_to > car_price)]

   car_price x.price_from x.price_to price_class
1:    190000        0e+00     199999           1
2:    190000        0e+00     199999           2
3:    500000        5e+05     599999           8

如果你提高汽车价格:

cars <- cars * 10
data_priceclass[cars, .(car_price,x.price_from,x.price_to,price_class),on = .(price_from <= car_price,price_to > car_price)]

   car_price x.price_from x.price_to price_class
1:   1900000           NA         NA          NA
2:   5000000           NA         NA          NA

【讨论】:

  • 感谢您的回答!我想我可能误解了 data.table 中的左连接是什么。从文档(cran.r-project.org/web/packages/data.table/data.table.pdf)它说:@ 987654331@。来自@David Arenburg 上面写的:X[Y] it means "for each value in Y find all the matching records in X"。我来自 SQL,left join 左侧的任何内容,例如A left join B on... 被解释为for each value in A find all the matching records in B,但这里似乎相反......我现在很困惑,你能澄清一下吗?
  • 我发现这个 tutorial 对于比较 data.tableSQL 语法很有用
  • 你是对的,X[Y] 将 Y 作为 SQL 中的左表,这可能会令人困惑,但 data.tablenever 说 left。在data.table 语法中,它意味着merge(X, Y, all.x=TRUE)
  • 这可能会有所帮助:cars[data_priceclass, .(x.car_price,i.price_class), on = .(car_price &gt;= price_from, car_price &lt; price_to)]。引用修改按顺序修改匹配行,所以190000先更新为1,再更新2,500000更新为8
  • 您可以通过相反的方式订购 price_class 来验证上述内容:data_priceclass &lt;- data_priceclass[order(-price_class)],这导致 price_class= 1 而不是 2 在 cars[data_priceclass, price_class := i.price_class, on = .(car_price &gt;= price_from, car_price &lt; price_to)] 之后
猜你喜欢
  • 1970-01-01
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
相关资源
最近更新 更多