expand.grid for data.frame using dplyr full_join

Viewed 2688

I am trying to get a function similar to expand.grid and works on data.frame.

I found a solution in Alternative to expand.grid for data.frames that uses merge function to implement this.

Since merge is quite slow compared to dplyr alternative full_join, so I try to use full_join to implement this function, but I couldn't get it done correctly. Here is an example I failed:

df <- data.frame(attribute = paste0('attr', rep(1:5, each=2)),
                 value = paste0(rep(1:5, each=2), rep(c('A','B'), 2)),
                 score = runif(10))
df
   attribute value      score
1      attr1    1A 0.75600171
2      attr1    1B 0.07086242
3      attr2    2A 0.92403325
4      attr2    2B 0.63414169
5      attr3    3A 0.78763834
6      attr3    3B 0.88576568
7      attr4    4A 0.75998967
8      attr4    4B 0.25205845
9      attr5    5A 0.99304728
10     attr5    5B 0.70389605

I tried to split df by attribute and join the list of score together:

dfList <- df %>%
  mutate(attribute=1) %>%
  split(df$attribute)

And I "expand.grid" all these 5 tables together by:

Reduce(function(x, y) {full_join(x, y, by=c('attribute'='attribute'))}, dfList)

However, the result is weird:

   attribute value.x    score.x value.y   score.y value.x    score.x value.y   score.y value     score
1          1      1A 0.75600171      2A 0.9240333      1A 0.75600171      2A 0.9240333    5A 0.9930473
2          1      1A 0.75600171      2A 0.9240333      1A 0.75600171      2A 0.9240333    5B 0.7038961
3          1      1A 0.75600171      2A 0.9240333      1A 0.75600171      2A 0.9240333    5A 0.9930473
4          1      1A 0.75600171      2A 0.9240333      1A 0.75600171      2A 0.9240333    5B 0.7038961
...

The first 2 tables are shown twice, which is not desired. But when I try this on the first 4 tables it works perfectly:

Reduce(function(x, y) {full_join(x, y, by=c('attribute'='attribute'))}, dfList[1:4])

   attribute value.x    score.x value.y   score.y value.x   score.x value.y   score.y
1          1      1A 0.75600171      2A 0.9240333      3A 0.7876383      4A 0.7599897
2          1      1A 0.75600171      2A 0.9240333      3A 0.7876383      4B 0.2520584
3          1      1A 0.75600171      2A 0.9240333      3B 0.8857657      4A 0.7599897
4          1      1A 0.75600171      2A 0.9240333      3B 0.8857657      4B 0.2520584 
...

Where I did wrong?

I'm using dplyr 0.4.3 with R version 3.2.4 on Ubuntu 14.04

1 Answers
Related