在滚动连接上按引用添加列

时间:2015-08-12 20:25:38

标签: r data.table

问题标题中描述了主要问题。直接进入下面的例子。

我有两个数据集:

library(data.table)
dt1 <- data.table(date = as.Date("2015-06-28")+c(0L,3L,5L,7L),
                  key="date")
dt2 <- data.table(date = as.Date("2015-06-30")+c(0:1,4L),
                  val = letters[7:9],
                  dummy = rep(NA,3),
                  key="date")

我希望使用滚动加入将val的{​​{1}}列添加到dt2
以下语句将产生与预期的类似的输出:

dt1

该陈述有两个问题:
1.我不想要dt2[dt1, roll=TRUE] # date val dummy # 1: 2015-06-28 NA NA # 2: 2015-07-01 h NA # 3: 2015-07-03 h NA # 4: 2015-07-05 i NA 栏 我想通过引用来做到这一点:

dummy

所以,我正在寻找滚动加入并为我的address(dt1) # [1] "0x3b57540" address(dt2[dt1, roll=TRUE]) # [1] "0x3b4e1f0" dt1添加列,预期输出:

dt2

当然# date val # 1: 2015-06-28 NA # 2: 2015-07-01 h # 3: 2015-07-03 h # 4: 2015-07-05 i 应与 magic 语句的address(dt1)匹配。

2 个答案:

答案 0 :(得分:3)

这是一种应该扩展的方法。

address(dt1)
# [1] "0x265a060"
ix = dt2[dt1, roll=TRUE, which=TRUE]
dt1[, val := dt2[ix, val]]
dt1
#          date val
# 1: 2015-06-28  NA
# 2: 2015-07-01   h
# 3: 2015-07-03   h
# 4: 2015-07-05   i
address(dt1)
# [1] "0x265a060"

或者不创建索引,直接如下:

dt1[, val := dt2[dt1, val, roll = TRUE]] ## (1)

请注意,这比执行效率更高:

dt1[, val := dt2[dt1, roll = TRUE]$val] ## (2)

(2)执行整个连接(具体化所有列),然后提取val,其中(1)直接提取列val

答案 1 :(得分:1)

这是一个解决方法;不完美,因为它仍然需要创造额外的记忆,虽然可能有一种方法可以避免这种情况不会立刻传到我身上(无论如何额外的记忆可能是最小的):

> address(dt1)
[1] "0x57b5230"

rng<-range(dt1[,range(date)],dt2[,range(date)])

x<-data.table(date=seq(from=rng[1],to=rng[2],by="day"),
              key="date")

> address(x)
[1] "0x6aa2df0"

x[dt2,setdiff(names(dt2),"date"):=mget(setdiff(names(dt2),"date"))
  ][,val:=zoo::na.locf(val,na.rm=F)]

> address(x)
[1] "0x6aa2df0"

> dt1[x,val:=i.val][]
         date val
1: 2015-06-28  NA
2: 2015-07-01   h
3: 2015-07-03   h
4: 2015-07-05   i

> address(dt1)
[1] "0x57b5230"