如何在R中的转换日期数据中创建面板数据集?

时间:2018-04-30 14:39:04

标签: r dplyr data.table

我的数据集结构如下:

ID   origin   destination  time
1     a        b           2
2     b        a           1
2     a        c           4
3     c        b           1
3     b        c           3

我想将其转换为ID时间面板数据集,如:

ID   location  time
1     a        1
1     b        2
1     b        3
1     b        4
2     a        1
2     a        2
2     a        3
2     c        4
3     b        1
3     b        2
3     c        3
3     c        4

所以基本上,我需要在主题不改变位置时创建面板行,并根据原点和目的地的信息填写它们应该位于的位置。 R中是否有任何功能可以顺利完成?我更喜欢使用data.table或dplyr的解决方案。

3 个答案:

答案 0 :(得分:4)

您可以为每个time创建一个表格,以便了解每个location的{​​{1}}:

ID

然后将原始数据放入长格式,推断出

  • origin适用于newDT = DT[, CJ(ID = unique(ID), time = 1:4)]
  • 目的地适用于time-1
time

...并使用滚动更新连接填写新表:

mDT = melt(DT, id = c("ID", "time"), value.name = "loc", variable.name = "loc_role")
mDT[loc_role == "origin", time := time - 1L]
mDT[, loc_role := NULL]
setorder(mDT, ID, time)

    ID time loc
 1:  1    1   a
 2:  1    2   b
 3:  2    0   b
 4:  2    1   a
 5:  2    3   a
 6:  2    4   c
 7:  3    0   c
 8:  3    1   b
 9:  3    2   b
10:  3    3   c

(Dplyr还没有滚动或更新联接,所以我猜这里没有模拟。)

工作原理

  • newDT[, location := mDT[.SD, on=.(ID, time), roll=TRUE, x.loc]] ID time location 1: 1 1 a 2: 1 2 b 3: 1 3 b 4: 1 4 b 5: 2 1 a 6: 2 2 a 7: 2 3 a 8: 2 4 c 9: 3 1 b 10: 3 2 b 11: 3 3 c 12: 3 4 c 采用某些向量的笛卡尔积,类似于CJ
  • expand.grid转换为长格式,将变量保存为melt
  • id =x[i, v := expr]选择的行上编辑了表v的列x
  • i就地排序
  • setorder .SD中的{li> j是指x[i,j] 选择的数据子集(x
  • i是滚动联接,其中的行由表x[i, on=, roll=, expr]ion=
  • 选择
  • 联接中的表达式roll=x.v
  • 中选择列v

关于最后一个项目符号,前缀xi.*中的列执行相同的操作。

答案 1 :(得分:3)

与Frank的解决方案类似的方法,但使用两个连接将是:

library(data.table)
res <- setDT(expand.grid(ID = unique(dt$ID), time = 1:4))

#Get origin
res[dt[,.(ID, origin, time = time - 1L)], location := origin, on = .(ID = ID, time = time)]

#Update origin and destination
res[dt, location := destination, on = c("ID", "time")][, location := zoo::na.locf(location), by = ID][order(ID, time)]

 #   ID time location
 #1:  1    1        a
 #2:  1    2        b
 #3:  1    3        b
 #4:  1    4        b
 #5:  2    1        a
 #6:  2    2        a
 #7:  2    3        a
 #8:  2    4        c
 #9:  3    1        b
#10:  3    2        b
#11:  3    3        c
#12:  3    4        c

答案 2 :(得分:3)

我认为你不需要为这个问题进行花哨的连接:

maxt = max(dt$time)
dt[, .(location = c(rep(origin[1], time[1] - 1), rep(destination, diff(c(time, maxt + 1)))),
       time = 1:maxt), by = ID]
#    ID location time
# 1:  1        a    1
# 2:  1        b    2
# 3:  1        b    3
# 4:  1        b    4
# 5:  2        a    1
# 6:  2        a    2
# 7:  2        a    3
# 8:  2        c    4
# 9:  3        b    1
#10:  3        b    2
#11:  3        c    3
#12:  3        c    4

根据OP示例,我假设在单个ID中,下一个原点与之前的目的地相同。