2017-03-15 65 views
0

我有一个数据框对象,其中变量的组合表示为1,但是由于没有绘制出所有组合,所以变量稀疏。R将数据帧列连接到部分匹配的网格

例如

A B C Outcome 
1 0 0 700 
0 1 0 900 
0 0 1 450 
1 1 0 280 
0 1 1 100 

...这是缺少潜在组合[101]和[111]

由此,我想扩大了A,B和C的所有组合,取结果价值组合存在的地方,如果不存在,则用零填充结果。

例如

A B C Outcome 
1 0 0 700 
1 1 0 280 
1 0 1 0   <- new row 
1 1 1 0   <- new row 
0 1 0 900 
0 1 1 100 
0 0 1 450 

恐怕我真的不知道如何在功能上做到这一点。我看了一下expand.grid() - 例如下面也采用plyr

expand.grid(rlply(n, c(0,1))) 

其中n = 3时给出

Var1 Var2 Var3 
1 0 0 0 
2 1 0 0 
3 0 1 0 
4 1 1 0 
5 0 0 1 
6 1 0 1 
7 0 1 1 
8 1 1 1 

这几乎让我的网,我后,但我现在还不清楚如何将这个“结果”值加入到这个网格中,特别是当n很大时(比如60或70个变量)。

任何帮助感激地收到!

回答

2
df <- read.table(text = 
"A B C Outcome 
1 0 0 700 
0 1 0 900 
0 0 1 450 
1 1 0 280 
0 1 1 100", 
header = TRUE) 

res <- 
    merge(
    x = do.call(what = "expand.grid", lapply(head(as.list(df), - 1), unique)), 
    y = df, 
    all.x = TRUE 
) 
res$Outcome[is.na(res$Outcome)] <- 0 
res 
# A B C Outcome 
# 1 0 0 0  0 
# 2 0 0 1  450 
# 3 0 1 0  900 
# 4 0 1 1  100 
# 5 1 0 0  700 
# 6 1 0 1  0 
# 7 1 1 0  280 
# 8 1 1 1  0 

编辑:

不能确定它是否应该在一个单独的答案,但这里是与tidyr包一个更优雅的方式:

library(tidyr) 

complete(df, A, B, C, fill = list(Outcome = 0)) 

如果你想避免输入全部60或70列名称:

complete_(df, cols = setdiff(names(df), "Outcome"), fill = list(Outcome = 0))