r中的条件连接

Hug*_*ugh 11 join r dplyr

我想有条件地将两个数据表连接在一起:

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

key.table <- 
  data.table(
    out = (0:10)/10,
    keyz = sort(runif(11))
  )

large.tbl <- 
  data.table(
    ab = rnorm(1e6),
    cd = runif(1e6)
  )
Run Code Online (Sandbox Code Playgroud)

根据以下规则:匹配的最小值outkey.tablekeyz值大于cd.我有以下内容:

library(dplyr)
large.tbl %>%
  rowwise %>%
  mutate(out = min(key.table$out[key.table$keyz > cd]))
Run Code Online (Sandbox Code Playgroud)

它提供了正确的输出.我遇到的问题是,我实际使用的rowwise操作似乎很昂贵,large.tbl除非它在特定的计算机上,否则会崩溃.是否有更少的内存昂贵的操作?以下似乎稍微快一点,但对我遇到的问题还不够.

large.tbl %>%
    group_by(cd) %>%
    mutate(out = min(key.table$out[key.table$keyz > cd]))
Run Code Online (Sandbox Code Playgroud)

这有点像data.table答案的问题,但答案不必使用该包.

Kha*_*haa 5

如果key.table$out还按照玩具示例中的顺序进行排序,则可以使用以下方法

ind <- findInterval(large.tbl$cd, key.table$keyz) + 1
large.tbl$out <- key.table$out[ind]
head(large.tbl)
#             ab         cd out
#1: -0.928567035 0.99473795  NA
#2: -0.294720447 0.41107393 0.5
#3: -0.005767173 0.91086585 1.0
#4:  2.404653389 0.66491244 0.8
#5:  0.763593461 0.09590456 0.1
#6: -0.799009249 0.50963409 0.5
Run Code Online (Sandbox Code Playgroud)

如果key.table$out没有排序,

ind <- findInterval(large.tbl$cd, key.table$keyz) + 1
vec <- rev(cummin(rev(key.table$out)))
large.tbl$out <- vec[ind]
Run Code Online (Sandbox Code Playgroud)


Mic*_*ico 4

你想要的是:

setkey(large.tbl, cd)
setkey(key.table, keyz)
key.table[large.tbl, roll = -Inf]
Run Code Online (Sandbox Code Playgroud)

参见?data.table> roll

适用于最后一个连接列,通常是日期,但可以是任何有序变量,不规则且包括间隙。如果roll=TRUEi的行与除最后一个x连接列之外的所有行匹配,并且最后一个连接列中的值i落在间隙中(包括在x该组的最后一个观察值之后),则x前滚中的主要值。使用修改后的二分搜索,此操作特别快。该操作也称为最后观察结转 (LOCF)。x通常,的键中不应有重复项,最后一个键列是日期(或时间或日期时间),并且x的键的所有列都连接在一起。dts一个常见的习惯用法是在一组标识符 ( ) 中选择同时期的常规时间序列 ( ids):DT[CJ(ids,dts),roll=TRUE]其中DT有一个 2 列键 ( id,date) 并CJ代表交叉连接。当roll为正数时,这会限制值的结转程度。roll=TRUE相当于roll=+Inf. 当roll为负数时,值向后滚动;即,下一个观察向后进行(NOCB)。用于-Inf无限回滚。当 roll 为 时"nearest",将连接最接近的值。

(公平地说,我认为这可以进行一些说明,它非常密集)

  • 公平地说,我正在研究详细的[vignettes](https://github.com/Rdatatable/data.table/issues/944)...我认为 data.table 用户对此非常了解。 (3认同)