【问题标题】:Conditional data.table merge with .EACHI条件 data.table 与 .EACHI 合并
【发布时间】:2017-04-02 22:00:14
【问题描述】:

我一直在玩新的data.table 条件合并功能,它非常酷。我有两个表,dtBigdtSmall,并且在发生此条件合并时,两个数据集中都有多个行匹配。有没有办法为这些多个匹配使用maxmin 之类的函数来聚合这些匹配?这是一个可重现的示例,它试图模仿我想要完成的事情。

设置环境

## docker run --rm -ti rocker/r-base
## install.packages("data.table", type = "source",repos = "http://Rdatatable.github.io/data.table")

创建两个假数据集

创建一个包含 50 行(每个 ID 10 个值)的“大”表。

library(data.table)
set.seed(1L)

# Simulate some data
dtBig <- data.table(ID=c(sapply(LETTERS[1:5], rep, 10, simplify = TRUE)), ValueBig=ceiling(runif(50, min=0, max=1000)))
dtBig[, Rank := frank(ValueBig, ties.method = "first"), keyby=.(ID)]

    ID ValueBig Rank
 1:  A      266    3
 2:  A      373    4
 3:  A      573    5
 4:  A      909    9
 5:  A      202    2
---                 
46:  E      790    9
47:  E       24    1
48:  E      478    2
49:  E      733    7
50:  E      693    6

创建一个类似于第一个的“小”数据集,但有 10 行(每个 ID 2 个值)

dtSmall <- data.table(ID=c(sapply(LETTERS[1:5], rep, 2, simplify = TRUE)), ValueSmall=ceiling(runif(10, min=0, max=1000)))

    ID ValueSmall
 1:  A        478
 2:  A        862
 3:  B        439
 4:  B        245
 5:  C         71
 6:  C        100
 7:  D        317
 8:  D        519
 9:  E        663
10:  E        407

合并

接下来我想通过ID 执行合并,并且只需要在ValueSmall 大于或等于ValueBig 的地方进行合并。对于比赛,我想在dtBig 中获取max 排名值。我尝试了两种不同的方式。方法 2 给了我想要的输出,但我不清楚为什么输出完全不同。它似乎只是返回最后一个匹配的值。

## Method 1
dtSmall[dtBig, RankSmall := max(i.Rank), by=.EACHI, on=.(ID, ValueSmall >= ValueBig)]

## Method 2
setorder(dtBig, ValueBig)
dtSmall[dtBig, RankSmall2 := max(i.Rank), by=.EACHI, on=.(ID, ValueSmall >= ValueBig)]

结果

    ID ValueSmall RankSmall RankSmall2 DesiredRank
 1:  A        478         1          4           4
 2:  A        862         1          7           7
 3:  B        439         3          4           4
 4:  B        245         1          2           2
 5:  C         71         1          1           1
 6:  C        100         1          1           1
 7:  D        317         1          2           2
 8:  D        519         3          5           5
 9:  E        663         2          5           5
10:  E        407         1          1           1

有没有更好的data.table 方法在多个匹配的另一个data.table 中获取最大值?

【问题讨论】:

  • 更新 - 在data.table github 上似乎存在与此问题相关的问题。 (github.com/Rdatatable/data.table/issues/733)

标签: r data.table


【解决方案1】:

接下来我想按 ID 执行合并,并且只需要在 ValueSmall 大于或等于 ValueBig 的地方进行合并。对于比赛,我想获取 dtBig 中的最大排名值。

setorder(dtBig, ID, ValueBig, Rank)
dtSmall[, r :=
  dtBig[.SD, on=.(ID, ValueBig <= ValueSmall), mult="last", x.Rank ]
]

    ID ValueSmall r
 1:  A        478 4
 2:  A        862 7
 3:  B        439 4
 4:  B        245 2
 5:  C         71 1
 6:  C        100 1
 7:  D        317 2
 8:  D        519 5
 9:  E        663 5
10:  E        407 1

我想对 dtBig 进行排序并取最后一个匹配行而不是通过 .EACHI 计算最大值要快得多,但我并不完全确定。如果您不喜欢排序,只需保存之前的排序顺序,以便以后恢复。


有没有办法为这些多个匹配使用 max 或 min 之类的函数来聚合这些匹配?

对于这个更普遍的问题,.EACHI 有效,只需确保您为目标表的每一行(在本例中为 dtSmall)都执行此操作,所以...

dtSmall[, r :=
  dtBig[.SD, on=.(ID, ValueBig <= ValueSmall), max(x.Rank), by=.EACHI ]$V1
]

【讨论】:

猜你喜欢
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
相关资源
最近更新 更多