2

I want to create a matrix of a powerset of a vector. Similar to this question on SO.

I have this

#data
a <- c("test1","test2","test3")

#result
data.table::rbindlist(
    sapply(1:3, function(i) as.data.frame(t(combn(a, i)))), fill = TRUE)
#>       V1    V2    V3
#> 1: test1  <NA>  <NA>
#> 2: test2  <NA>  <NA>
#> 3: test3  <NA>  <NA>
#> 4: test1 test2  <NA>
#> 5: test1 test3  <NA>
#> 6: test2 test3  <NA>
#> 7: test1 test2 test3

Created on 2021-04-14 by the reprex package (v1.0.0)

I want to transform it in to this (I dont want the dots as well if that is possible):

library(tidyr)
#> Warning: replacing previous import 'vctrs::data_frame' by 'tibble::data_frame'
#> when loading 'dplyr'
tribble(
    ~test1, ~test2, ~ test3,
    "x", ".", ".",
    ".", "x", ".",
    ".", ".", "x",
    "x", "x", ".",
    "x", ".", "x",
    ".", "x", "x",
    "x", "x", "x"
)
#> # A tibble: 7 x 3
#>   test1 test2 test3
#>   <chr> <chr> <chr>
#> 1 x     .     .    
#> 2 .     x     .    
#> 3 .     .     x    
#> 4 x     x     .    
#> 5 x     .     x    
#> 6 .     x     x    
#> 7 x     x     x

Created on 2021-04-14 by the reprex package (v1.0.0)

ok1more
  • 779
  • 6
  • 15

1 Answers1

2

Here, we could get the combn to return the table of factor converted x with levels specified as 'a', rbind the inner list and then the outer list to return a matrix. Change the binary output to '.' and 'x' for 0 and 1

out <- do.call(rbind, lapply(1:3, function(i) 
    do.call(rbind, combn(a, i, FUN = function(x)
      table(factor(x, levels = a)), simplify = FALSE))))

out[] <- c('.', 'x')[1 + out]
as.data.frame(out)
#   test1 test2 test3
#1     x     .     .
#2     .     x     .
#3     .     .     x
#4     x     x     .
#5     x     .     x
#6     .     x     x
#7     x     x     x
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Is there a way that we use a space or blank or something even more minimalist than a dot? – ok1more Apr 14 '21 at 19:30
  • @AshishSinghal it is just the `c('.', 'x')[1 + out]` that needs change i.t. `c(' ', 'x')[1 + out]` – akrun Apr 14 '21 at 19:32
  • gotcha.. it works but I kept getting `Error in 1 + out : non-numeric argument to binary operator` when I ran the `out[] <- c('', 'x')[1 + out]` – ok1more Apr 14 '21 at 19:37
  • 1
    @ok1more it is because you already updated the `out` once and now it is not numeric. Try creating the object again with `out <- do.call(... – akrun Apr 14 '21 at 19:38