使用Data.table进行笛卡尔滚动连接

时间:2018-06-19 03:19:51

标签: r join data.table

我有两张桌子:

  • dat:包含数据

  • 日期:包含日期表

library(data.table)

dates = structure(list(date = structure(c(17562, 17590, 17621, 17651, 
                              17682, 17712, 17743, 17774, 17804, 17835, 17865, 17896), class = "Date")), 
      row.names = c(NA, -12L), class = "data.frame")


dat = structure(list(date = structure(c(17546, 17743, 17778, 17901, 
                              17536, 17806, 17901, 17981, 17532, 17722, 17969, 18234), class = "Date"), 
           country = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 
                                 3L, 3L, 3L), .Label = c("AAA", "BBB", "CCC"), class = "factor"), 
           state = structure(c(1L, 1L, 2L, 3L, 4L, 1L, 2L, 5L, 6L, 1L, 
                               2L, 2L), .Label = c("S1", "S2", "S3", "S4", "S5", "S6"), class = "factor"), 
           item = structure(c(1L, 2L, 4L, 6L, 3L, 5L, 3L, 2L, 2L, 4L, 
                              5L, 7L), .Label = c("M1", "M2", "M3", "M4", "M5", "M6", "M7"
                              ), class = "factor"), value = c(67L, 10L, 50L, 52L, 93L, 
                                                              50L, 62L, 46L, 6L, 30L, 30L, 14L)), row.names = c(NA, -12L
                                                              ), class = "data.frame")


dates = data.table(dates)
dat = data.table(dat)


setkey(dates, date)
setkey(dat, date)

我之后的结果如下。即,对每个单独的dat行进行滚动连接,然后组合结果。

rbind(
dat[1,][dates, roll = 90],
dat[2,][dates, roll = 90],
dat[3,][dates, roll = 90],
...
dat[12,][dates, roll = 90]
)

我的实际数据集要大得多,因此列出每一行数据并不实用。如果没有循环,是否有一种简单的方法来做同样的事情?

2 个答案:

答案 0 :(得分:1)

如果我理解您的意图,您希望将记录翻转90天。 我使用交叉连接,然后使用翻转标准来子集

原始表:

library(data.table)

dates = structure(list(date = structure(c(17562, 17590, 17621, 17651, 
                                          17682, 17712, 17743, 17774, 17804, 17835, 17865, 17896), class = "Date")), 
                  row.names = c(NA, -12L), class = "data.frame")


dat = structure(list(date = structure(c(17546, 17743, 17778, 17901, 
                                        17536, 17806, 17901, 17981, 17532, 17722, 17969, 18234), class = "Date"), 
                     country = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 
                                           3L, 3L, 3L), .Label = c("AAA", "BBB", "CCC"), class = "factor"), 
                     state = structure(c(1L, 1L, 2L, 3L, 4L, 1L, 2L, 5L, 6L, 1L, 
                                         2L, 2L), .Label = c("S1", "S2", "S3", "S4", "S5", "S6"), class = "factor"), 
                     item = structure(c(1L, 2L, 4L, 6L, 3L, 5L, 3L, 2L, 2L, 4L, 
                                        5L, 7L), .Label = c("M1", "M2", "M3", "M4", "M5", "M6", "M7"
                                        ), class = "factor"), value = c(67L, 10L, 50L, 52L, 93L, 
                                                                        50L, 62L, 46L, 6L, 30L, 30L, 14L)), row.names = c(NA, -12L
                                                                        ), class = "data.frame")


dates = data.table(dates)
dat = data.table(dat)

注意,我没有设置密钥。

我正在使用引用中的交叉连接函数:How to do cross join in R?

CJ.table.1 <- function(X,Y)
  setkey(X[,c(k=1,.SD)],k)[Y[,c(k=1,.SD)],allow.cartesian=TRUE][,k:=NULL]

然后我交叉连接,滚动连接的子集,重命名列和排序

dsn1<-CJ.table.1(dat,dates)[i.date-date<=90 & i.date-date>=0][,.(date=i.date,country, state, item, value)][order(country, state, item, value,date),]

答案 1 :(得分:0)

这不一定是最好的方法,但你可以在这里写一个循环来迭代你的数据:

Property.Value

编辑:刚刚看到你说过#34;没有循环&#34;,这是漫长的一天。这是解决问题的一种方法。