我正在努力解决以下问题。
如果有一个(大)数据框,则包含以下内容:
我想确保对于每个时间间隔的每个唯一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
故意排除第8行。通过这种方式,我模拟了一个“缺失值”&#39; (缺少Quantity
)ID&#39; 2-b&#39; (ProductID-CustomerID
)了解时间价值&#34; 2012-02&#34;。
我想要做的是调整data.frame,以便对所有时间值(这些都是已知的,在这个例子中只是&#34; 2012-01&#34;&#34; 2012-02& #34;),对于所有ID组合(这些都是预先知道的,但这是数据框中的所有唯一ID组合&#39;,因此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
最终目标是为这些ID组合创建时间序列,因此我希望拥有所有时间值的数量。我需要进行不同的聚合(按时)并使用来自大数据集的不同级别的ID
我尝试了几件事,例如melt
包中的cast
和reshape
。但到目前为止,我没有设法做到这一点。下一步是使用for循环等创建一个函数,但从性能角度来看这并不是很有用。
也许有一种更简单的方法可以立即创建时间序列,提供像test
这样的数据框架。有没有人对这个有想法?
提前致谢!
请注意,在实际问题中,有两个以上的ID列&#39;。
编辑:
我应该进一步描述这个问题。 “时间”与“时间”之间存在差异。栏目和“ID&#39;列。关于 joran 这个问题的第一个(也是伟大的!)答案,也许并没有从我想要的东西中得到清楚的理解(我给出的例子并没有明确区别)。我上面说过:
所有ID组合(这些都是前期未知的,但这是全部 数据框中的唯一ID组合&#39;,因此唯一的ID集合 ID列)
所以我不想要所有可能的ID组合&#39;但是&#39;数据中的所有ID组合&#39;。 对于每个组合,我想要每个唯一时间值的值。
让我通过将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
这意味着我想在结果数据框中没有&#39; 3-b&#39; 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>
所以我不希望行6
和12
在这里。
为了克服这个问题,我在下面找到了一个解决方案。在这里,我拆分了独特的时间列&#39;和唯一的ID组合&#39;。因此,与上面的区别在于“组合”这个词。并非每个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
对此有何评论?
这是一种优雅的方式,还是有更好的方法?
答案 0 :(得分:20)
使用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
NA
可以在事实之后使用子集和is.na
替换您选择的任何值。