从不平衡到平衡面板

时间:2014-09-05 22:42:53

标签: r data.table dplyr

我用魔杖填写组中缺少的行,其中组由特定的(id1,id2)定义。

例如,我有一个

的数据集
  id1   id2  year  value
  33    29  1990     3.5
  33    29  1993     3.3
  33    29  1994     3.1
  32    28  1992     3.1
  32    28  1993     4.5

我想获取以下数据集

 id1   id2  year   value
  33    29  1990     3.5
  33    29  1991      NA
  33    29  1992      NA
  33    29  1993     3.3
  33    29  1994     3.1
  32    28  1992     3.1
  32    28  1993     4.5

请注意,不需要为第二个组创建包含year==1991,year==1992的行。该示例已经过简化,但该解决方案应该适用于字符串/数字,以及多个值列,而不仅仅是一个。

2 个答案:

答案 0 :(得分:2)

怎么样?

require(data.table)
DT = data.table(id1 = c(33,33,33,32,32),
                id2 = c(29,29,29,28,28),  
               year = c(1990,1993,1994,1991,1992),
              value = c(3.5,3.3,3.1,3.1,4.5))


setkey(DT, id1,id2,year)
ans = DT[, list(year = seq.int(year[1L], year[.N])), by = list(id1,id2)]
ans = DT[setkey(ans)]
#    id1 id2 year value
# 1:  32  28 1991   3.1
# 2:  32  28 1992   4.5
# 3:  33  29 1990   3.5
# 4:  33  29 1991    NA
# 5:  33  29 1992    NA
# 6:  33  29 1993   3.3
# 7:  33  29 1994   3.1

答案 1 :(得分:0)

这里的行数可能更少,但这都是使用标准data.frames(无data.table)完成的。这是dput()表单

中的示例数据
dd <- structure(list(id1 = c(33L, 33L, 33L, 32L, 32L), id2 = c(29L, 
29L, 29L, 28L, 28L), year = c(1990L, 1993L, 1994L, 1992L, 1993L
), value = c(3.5, 3.3, 3.1, 3.1, 4.5)), .Names = c("id1", "id2", 
"year", "value"), class = "data.frame", row.names = c(NA, -5L
))

我将使用辅助函数来摆脱丑陋的默认rownames

unrowname <- function(x) `rownames<-`(x, NULL)

然后我用

转换数据
do.call(rbind, unname(lapply(split(dd, interaction(dd$id1, dd$id2, drop=T)), function(x) {
    r = seq(from=min(x$year), to=max(x$year)); 
    cbind(unrowname(x[1,1:2]), year=r, value=x$value[match(r, x$year)])
})))

给出了

  id1 id2 year value
1  32  28 1992   3.1
2  32  28 1993   4.5
3  33  29 1990   3.5
4  33  29 1991    NA
5  33  29 1992    NA
6  33  29 1993   3.3
7  33  29 1994   3.1

所以只要你不介意行重组,它应该可以正常工作。