我正在努力解决以下问题.
如果有一个(大)数据框,则具有以下内容:
我想确保对于每个时间间隔的每个唯一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
我试了好东西,比如与melt和cast从reshape包.但到目前为止,我没有设法做到这一点.下一步是使用for循环等创建一个函数,但从性能角度来看这并不是很有用.
也许有一种更简单的方法可以立即创建时间序列,给出一个像data.frame这样的数据test.有没有人对这一个有所了解?
提前致谢!
请注意,在实际问题中,有两个以上的"ID列".
编辑:
我应该进一步描述这个问题."时间"列和"ID"列之间存在差异.关于joran问题的第一个(也是伟大的!)答案,或许没有从我想要的东西中得到清楚的理解(我给出的例子没有明确区别).我上面说过:
对于所有ID组合(这些都是预先知道的,但这是'数据框中的所有唯一ID组合',因此ID列上的唯一ID组合)
所以我不想要"所有可能的ID组合",而是"数据中的所有ID组合".对于每个组合,我想要每个唯一时间值的值.
让我通过扩展test到test2以下来说清楚
> 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)
所以我不希望行6和12在这里.
为了解决这个问题,我在下面找到了一个解决方案.在这里,我将"唯一时间列"和"唯一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.grid和merge:
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.