条件data.table与.EACHI合并

Mik*_*han 6 r data.table

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

设置环境

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

创建两个假数据集

创建一个包含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
Run Code Online (Sandbox Code Playgroud)

创建一个类似于第一个的"小"数据集,但有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
Run Code Online (Sandbox Code Playgroud)

合并

我接下来想要执行合并,ID只需要合并ValueSmall大于或等于的地方ValueBig.对于比赛,我想要获得max排名值dtBig.我尝试过两种不同的方式.方法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)]
Run Code Online (Sandbox Code Playgroud)

结果

    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
Run Code Online (Sandbox Code Playgroud)

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

Fra*_*ank 6

接下来,我想按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
Run Code Online (Sandbox Code Playgroud)

我想对dtBig进行排序并采用最后匹配的行要比用.EACHI计算最大值要快得多,但是我不确定。如果您不喜欢排序,只需保存以前的排序顺序,以便可以将其还原为之后的顺序。


有没有一种方法可以针对这些多个匹配使用诸如max或min之类的函数来汇总这些匹配?

对于这个更普遍的问题,.EACHI可以正常工作,只需确保对目标表的每一行都进行此操作(在这种情况下为dtSmall),所以...

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

  • 由于尚无关于联接的data.table小插图,因此人们可以查看我的注释以更好地了解语法:http://franknarf1.github.io/r-tutorial/_book/tables.html#dt-joins(本节“更新联接”)。 (2认同)