R:在时间相关数据帧中查找并添加缺失(/非现有)行

FBE*_*FBE 15 r

我正在努力解决以下问题.

如果有一个(大)数据框,则具有以下内容:

  • 列的组合是几个列,是"唯一"组合,比如ID
  • 与时间相关的专栏
  • 与度量相关的列

我想确保对于每个时间间隔的每个唯一ID,数据框中都有一个度量.如果不是,我想为该时间/ ID添加0(或NA)度量.

要说明问题,请创建以下test数据框:

test <- data.frame(
    YearWeek   =rep(c("2012-01","2012-02"),each=4),
    ProductID  =rep(c(1,2), times=4),
    CustomerID =rep(c("a","b"), each=2, times=2),
    Quantity   =5:12
)[1:7,]

  YearWeek ProductID CustomerID Quantity
1  2012-01         1          a        5
2  2012-01         2          a        6
3  2012-01         1          b        7
4  2012-01         2          b        8
5  2012-02         1          a        9
6  2012-02         2          a       10
7  2012-02         1          b       11
Run Code Online (Sandbox Code Playgroud)

第8行是故意遗漏的.这样,我为ID'2 Quantity-b'(ProductID-CustomerID)模拟时间值"2012-02" 的"缺失值"(缺失).

我想做的是调整data.frame,使所有时间值(这些都是已知的,在本例中只是"2012-01"和"2012-02"),对于所有ID组合(这些是事先不知道,但这是'数据框中的所有唯一ID组合',因此ID列上的唯一集合),数据框中有数量.

这应该是这个例子的结果(如果我们选择NA缺失值,通常我想控制它):

  YearWeek ProductID CustomerID Quantity
1  2012-01         1          a        5
2  2012-01         2          a        6
3  2012-01         1          b        7
4  2012-01         2          b        8
5  2012-02         1          a        9
6  2012-02         2          a       10
7  2012-02         1          b       11
8  2012-02         2          b       NA
Run Code Online (Sandbox Code Playgroud)

最终目标是为这些ID组合创建时间序列,因此我希望获得所有时间值的数量.我需要进行不同的聚合(按时)并使用来自大数据集的不同级别的ID

我试了好东西,比如与meltcastreshape包.但到目前为止,我没有设法做到这一点.下一步是使用for循环等创建一个函数,但从性能角度来看这并不是很有用.

也许有一种更简单的方法可以立即创建时间序列,给出一个像data.frame这样的数据test.有没有人对这一个有所了解?

提前致谢!

请注意,在实际问题中,有两个以上的"ID列".


编辑:

我应该进一步描述这个问题."时间"列和"ID"列之间存在差异.关于joran问题的第一个(也是伟大的!)答案,或许没有从我想要的东西中得到清楚的理解(我给出的例子没有明确区别).我上面说过:

对于所有ID组合(这些都是预先知道的,但这是'数据框中的所有唯一ID组合',因此ID列上的唯一ID组合)

所以我不想要"所有可能的ID组合",而是"数据中的所有ID组合".对于每个组合,我想要每个唯一时间值的值.

让我通过扩展testtest2以下来说清楚

> test2 <- rbind(test, c("2012-02", 3, "a", 13))
> test2
  YearWeek ProductID CustomerID Quantity
1  2012-01         1          a        5
2  2012-01         2          a        6
3  2012-01         1          b        7
4  2012-01         2          b        8
5  2012-02         1          a        9
6  2012-02         2          a       10
7  2012-02         1          b       11
8  2012-02         3          a       13
Run Code Online (Sandbox Code Playgroud)

这意味着我想在结果数据框中没有'3-b'ID组合,因为这种组合不在其中test2.如果我使用第一个答案的方法,我将得到以下内容:

> vals2 <- expand.grid(YearWeek = unique(test2$YearWeek),
                       ProductID = unique(test2$ProductID),
                       CustomerID = unique(test2$CustomerID))

> merge(vals2,test2,all = TRUE)
   YearWeek ProductID CustomerID Quantity
1   2012-01         1          a        5
2   2012-01         1          b        7
3   2012-01         2          a        6
4   2012-01         2          b        8
5   2012-01         3          a     <NA>
6   2012-01         3          b     <NA>
7   2012-02         1          a        9
8   2012-02         1          b       11
9   2012-02         2          a       10
10  2012-02         2          b     <NA>
11  2012-02         3          a       13
12  2012-02         3          b     <NA>
Run Code Online (Sandbox Code Playgroud)

所以我不希望行612在这里.

为了解决这个问题,我在下面找到了一个解决方案.在这里,我将"唯一时间列"和"唯一ID组合"分开.因此,与上面的区别是"组合"这个词,并不是每个ID列都是唯一的.

> temp_merge <- merge(unique(test2["YearWeek"]),
                      unique(test2[c("ProductID", "CustomerID")]))

> merge(temp_merge,test2,all = TRUE)
   YearWeek ProductID CustomerID Quantity
1   2012-01         1          a        5
2   2012-01         1          b        7
3   2012-01         2          a        6
4   2012-01         2          b        8
5   2012-01         3          a     <NA>
6   2012-02         1          a        9
7   2012-02         1          b       11
8   2012-02         2          a       10
9   2012-02         2          b     <NA>
10  2012-02         3          a       13
Run Code Online (Sandbox Code Playgroud)

对这个有什么评论?

这是一种优雅的方式,还是有更好的方法?

jor*_*ran 21

使用expand.gridmerge:

vals <- expand.grid(YearWeek = unique(test$YearWeek),
                    ProductID = unique(test$ProductID),
                    CustomerID = unique(test$CustomerID))
> merge(vals,test,all = TRUE)
  YearWeek ProductID CustomerID Quantity
1  2012-01         1          a        5
2  2012-01         1          b        7
3  2012-01         2          a        6
4  2012-01         2          b        8
5  2012-02         1          a        9
6  2012-02         1          b       11
7  2012-02         2          a       10
8  2012-02         2          b       NA
Run Code Online (Sandbox Code Playgroud)

NAS可与任何您选择使用子集和值在事后被替换is.na.