如何使用在非等式连接X [Y,...]中指定和提取X和Y中的变量?

时间:2017-06-20 01:19:33

标签: r data.table

此问题提供了有关如何将基本by.x = by.y =中的Rmerge参数转换为data.table语法的示例,以指定不同命名的列作为连接键:

data.table merge by multiple columns

但是,我无法解决如何为非equi连接做同样的事情,我对输出感到非常困惑。

示例数据:

set.seed(0)
tmp_dt1<- data.table(grp = c(1,2), time = runif(100))
tmp_dt2 <- data.table(grp = c(1,2), time = c(0.1, 0.5))
tmp_dt2 <- tmp_dt2[, time_to := time + 0.2]
tmp_dt2 <- tmp_dt2[, time_from := time] # for clarity, rename time variable

我想在grp之后将这两个表等同加入,然后是非等式连接,这样我才能time保持tmp_dt1 time_to之间的time_from }和tmp_dt1[tmp_dt2, , on = c("grp", "time>=time", "time<=time_to")]。据我所知> tmp_dt1[tmp_dt2, , on = c("grp", "time>=time", "time<=time_to")] grp time time.1 time_from 1: 1 0.1 0.3 0.1 2: 1 0.1 0.3 0.1 3: 1 0.1 0.3 0.1 4: 1 0.1 0.3 0.1 5: 1 0.1 0.3 0.1 6: 1 0.1 0.3 0.1 7: 1 0.1 0.3 0.1 ... 做我想要的事情:

x.time

让我感到困惑的是time.1缺失,并且结果列名称非常混乱。例如,为什么有一个名为tmp_dt1[tmp_dt2, , on = c("grp", "time>=y.time", "time<=y.time_to")]的列?我想澄清语法,以便 grp y.time y.time_to time_from 1: 1 0.1 0.3 0.1 2: 1 0.1 0.3 0.1 3: 1 0.1 0.3 0.1 4: 1 0.1 0.3 0.1 5: 1 0.1 0.3 0.1 6: 1 0.1 0.3 0.1 7: 1 0.1 0.3 0.1 ... 生成:

x.time
除了y中的所有列之外,

还有一些如何提取列> tmp_dt1[tmp_dt2, , on = c("grp", "time>=y.time", "time<=y.time_to")] Error in `[.data.table`(tmp_dt1, tmp_dt2, , on = c("grp", "time>=y.time", : Column(s) [y.time,y.time_to] not found in i 。不幸的是,这失败了错误:

> tmp_dt1[tmp_dt2, .(grp, time, time_from = i.time, time_to = i.time_to), on = c("grp", "time>=time", "time<=time_to")]
    grp time time_from time_to
 1:   1  0.1       0.1     0.3
 2:   1  0.1       0.1     0.3
 3:   1  0.1       0.1     0.3
 4:   1  0.1       0.1     0.3
 5:   1  0.1       0.1     0.3
 6:   1  0.1       0.1     0.3
 7:   1  0.1       0.1     0.3

尝试以下内容也不会产生我的期望,而是得到:

time

tmp_dt1$time列与{{1}}没有任何相似之处。

2 个答案:

答案 0 :(得分:1)

我认为你想要这样的东西,使用library(dplyr) merged <- inner_join(tmp_dt1, tmp_dt2, by="grp") %>% rowwise() %>% filter(between(time.x, time_from, time_to)) %>% ungroup()

inner_join
{p> grp1等于rowwise()的联合。 filter()指定我希望按行发生以下语句。 between将按条件过滤行。该条件使用time.x >= time_from,其中包含time.x <= time_toungroup。最后,按行data.frame,以防您想要正常 {{1}}。

答案 1 :(得分:1)

为防止混淆,我建议重命名data.tables中具有相同名称的列,并创建非equi连接列列的副本。

setnames(tmp_dt2, "time", "time_dt2") tmp_dt2[, c("time_from_join", "time_to_join"):=list(time_from, time_to)] tmp_dt1[ , time_join := time]

然后我们可以加入,然后扔掉data.table在非equi连接中混乱的所有临时列。

tmp_dt1[tmp_dt2, on=.(grp==grp, time_join >= time_from_join, time_join <= time_to_join)][ , c("grp", "time", "time_from", "time_to", "time_dt2")]

grp time time_from time_to time_dt2 1: 1 0.1079436 0.1 0.3 0.1 2: 1 0.1216919 0.1 0.3 0.1 3: 1 0.1255551 0.1 0.3 0.1 4: 1 0.1433044 0.1 0.3 0.1 ...