Genera una lista di tutte le possibili combinazioni di elementi del vettore

Sto cercando di generare tutte le combinazioni possibili di 0 e di 1 in un vettore di lunghezza 14. C’è un modo semplice per ottenere quell’output come elenco di vettori, o anche meglio, come dataframe?

Per dimostrare meglio ciò che sto cercando, supponiamo che io voglia solo un vettore di lunghezza 3. Vorrei essere in grado di generare quanto segue:

(1,1,1), (0,0,0), (1,1,0), (1,0,0), (1,0,1), (0,1,0), (0,1,1), (0,0,0) 

Qualsiasi aiuto sarebbe apprezzato!

Grazie,

Stai cercando expand.grid .

 expand.grid(0:1, 0:1, 0:1) 

Oppure, per il caso lungo:

 n <- 14 l <- rep(list(0:1), n) expand.grid(l) 

In alternativa all’approccio di @ Justin, puoi anche utilizzare CJ dal pacchetto “data.table”. Qui, ho anche fatto uso di replicate per creare la mia lista di 14 zero e uno.

 library(data.table) do.call(CJ, replicate(14, 0:1, FALSE)) # V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 # 1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # 2: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 # 3: 0 0 0 0 0 0 0 0 0 0 0 0 1 0 # 4: 0 0 0 0 0 0 0 0 0 0 0 0 1 1 # 5: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 # --- # 16380: 1 1 1 1 1 1 1 1 1 1 1 0 1 1 # 16381: 1 1 1 1 1 1 1 1 1 1 1 1 0 0 # 16382: 1 1 1 1 1 1 1 1 1 1 1 1 0 1 # 16383: 1 1 1 1 1 1 1 1 1 1 1 1 1 0 # 16384: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

Ci sono 16384 possibili permutazioni. È ansible utilizzare il pacchetto iterpc per recuperare il risultato in modo iterativo.

 library(iterpc) I = iterpc(2, 14, label=c(0,1), order=T, replace=T) getnext(I) # [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 getnext(I) # [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 getnext(I) # [1] 0 0 0 0 0 0 0 0 0 0 0 0 1 0 

Se vuoi tutti i risultati, puoi comunque usare getall(I) .

Dato che hai a che fare con gli 0 e gli 1, sembra naturale pensare agli interi in termini di bit. Usando una funzione che è stata leggermente modificata da questo post ( MyIntToBit sotto), insieme alla tua scelta di apply funzioni, possiamo ottenere il risultato desiderato.

 MyIntToBit <- function(x, dig) { i <- 0L string <- numeric(dig) while (x > 0) { string[dig - i] <- x %% 2L x <- x %/% 2L i <- i + 1L } string } 

Se vuoi una lista, usa lapply modo:

 lapply(0:(2^14 - 1), function(x) MyIntToBit(x,14)) 

Se preferisci una matrice, sapply che sapply fare il trucco:

 sapply(0:(2^14 - 1), function(x) MyIntToBit(x,14)) 

Di seguito sono riportati gli output di esempio:

 > lapply(0:(2^3 - 1), function(x) MyIntToBit(x,3)) [[1]] [1] 0 0 0 [[2]] [1] 0 0 1 [[3]] [1] 0 1 0 [[4]] [1] 0 1 1 [[5]] [1] 1 0 0 [[6]] [1] 1 0 1 [[7]] [1] 1 1 0 [[8]] [1] 1 1 1 > sapply(0:(2^3 - 1), function(x) MyIntToBit(x,3)) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] 0 0 0 0 1 1 1 1 [2,] 0 0 1 1 0 0 1 1 [3,] 0 1 0 1 0 1 0 1 

tidyr ha un paio di opzioni simili a expand.grid() .

tidyr::crossing() restituisce un tibble e non converte stringhe in fattori (anche se potresti fare expand.grid(..., stringsAsFactors = F) ).

 library(tidyr) crossing(var1 = 0:1, var2 = 0:1, var3 = 0:1) # A tibble: 8 x 3 var1 var2 var3    1 0 0 0 2 0 0 1 3 0 1 0 4 0 1 1 5 1 0 0 6 1 0 1 7 1 1 0 8 1 1 1 

tidyr::expand() può dare entrambe le combinazioni di soli valori che appaiono nei dati, come questo:

 expand(mtcars, nesting(vs, cyl)) # A tibble: 5 x 2 vs cyl   1 0 4 2 0 6 3 0 8 4 1 4 5 1 6 

o tutte le possibili combinazioni di due variabili, anche se non c’è un’osservazione con quei valori specifici nei dati nei dati, come questo:

 expand(mtcars, vs, col) # A tibble: 6 x 2 vs cyl   1 0 4 2 0 6 3 0 8 4 1 4 5 1 6 6 1 8 

(Puoi vedere che non ci sono state osservazioni nei dati originali dove vs == 1 & cyl == 8)

tidyr::complete() può anche essere usato in modo simile a expand.grid() . Questo è un esempio dei documenti:

 df <- dplyr::tibble( group = c(1:2, 1), item_id = c(1:2, 2), item_name = c("a", "b", "b"), value1 = 1:3, value2 = 4:6 ) df %>% complete(group, nesting(item_id, item_name)) # A tibble: 4 x 5 group item_id item_name value1 value2      1 1 1 a 1 4 2 1 2 b 3 6 3 2 1 a NA NA 4 2 2 b 2 5 

Questo fornisce tutte le possibili combinazioni di item_id e item_name per ciascun gruppo: crea una linea per il gruppo 2 item_id 1 e item_name a.