data.table与两个键值合并

时间:2015-03-18 03:42:48

标签: r data.table

数据

我有一个“高”数据集,在单位级别通过时间重复观察,但间隔是不规则的。有4e6个观察,所以我想将解决方案保存在data.table中。

library(data.table)

d <- data.frame(let = rep(LETTERS[1:10], times = 2),
                num = rep(c(2001,2002), each = 10),
                vals = 1:20,
                lagNum = c(rep(c(NA, 2002), times = 5), rep(NA, 10)) 
                ) # there are missing values in the object 

d[c(1:5, 16:20),]

##    let  num vals lagNum
## 1    A 2001    1     NA
## 2    B 2001    2   2002
## 3    C 2001    3     NA
## 4    D 2001    4   2002
## 5    E 2001    5     NA
## 16   F 2002   16     NA
## 17   G 2002   17     NA
## 18   H 2002   18     NA
## 19   I 2002   19     NA
## 20   J 2002   20     NA

如果它有助于将任务锚定在现实世界中,那么这些单位就是国家,而且反复观察的是各国举行选举的年份。

目标

我想将vals_ {unit,past}中的单位值传递给vals_ {unit,present}。从某种意义上说,这就像创建一个更广泛的数据集:shuffles:在当前重现的高层观察到更广泛的数据。

我已经知道这不是动物园或其他时间序列应用的情况;我认为这不是重塑调用的任何版本,而是合并/连接。我也知道this responsethis response正朝着正确的方向前进,但是没有到达那里。

将其作为data.frame运行非常简单:

dMerge <- merge(x = d[!(is.na(d$lagNum)), ],
                y = d[, c("let", "num", "vals")],
                by.x = c("let", "lagNum"),
                by.y = c("let", "num")
                )
dMerge
##   let lagNum  num vals.x vals.y
## 1   B   2002 2001      2     12
## 2   D   2002 2001      4     14
## 3   F   2002 2001      6     16
## 4   H   2002 2001      8     18
## 5   J   2002 2001     10     20

作为data.table

我的第一个想法是复制data.table并适当地分配键值:

dat <- data.table(let = rep(LETTERS[1:10], times = 2),
                 num = rep(c(2001,2002), each = 10),
                 vals = 1:20,
                 lagNum = c(rep(c(NA, 2002), times = 5), rep(NA, 10))
                 )
setkeyv(dat, cols = c("let", "num"))

dat2 <- dat
setkeyv(dat2, cols = c("let", "lagNum"))

mDat <- merge(dat, dat2)

......如果这个有用,我可能会用它来运行。但事实并非如此,并且似乎并不特别“数据。表”是大肆复制数据。

1 个答案:

答案 0 :(得分:3)

尝试

library(data.table)#data.table_1.9.5
dat2 <- copy(dat)
setkeyv(dat2, cols = c("let", "lagNum"))
dat2[dat, nomatch =0][, i.lagNum:= NULL][]
#     let  num vals lagNum i.vals
#1:   B 2001    2   2002     12
#2:   D 2001    4   2002     14
#3:   F 2001    6   2002     16
#4:   H 2001    8   2002     18
#5:   J 2001   10   2002     20

或者您可以对原始数据集进行子集化,然后在设置密钥后进行连接。

dat2 <- dat[!is.na(lagNum)]
setkey(dat2, let, lagNum)
setkey(dat, let, num)
dat2[dat, nomatch=0][, i.lagNum := NULL][]
#   let  num vals lagNum i.vals
#1:   B 2001    2   2002     12
#2:   D 2001    4   2002     14
#3:   F 2001    6   2002     16
#4:   H 2001    8   2002     18
#5:   J 2001   10   2002     20