J'essaie de générer toutes les combinaisons possibles de 0 et de 1 dans un vecteur de longueur 14. Existe-t-il un moyen facile d'obtenir cette sortie sous forme de liste de vecteurs, ou mieux encore, une trame de données?
Pour mieux démontrer ce que je recherche, supposons que je ne veux qu'un vecteur de longueur 3. Je voudrais pouvoir générer ce qui suit:
(1,1,1), (0,0,0), (1,1,0), (1,0,0), (1,0,1), (0,1,0), (0,1,1), (0,0,0)
Toute aide serait appréciée!
Merci,
Vous cherchez expand.grid
.
expand.grid(0:1, 0:1, 0:1)
Ou, pour le cas long:
n <- 14
l <- rep(list(0:1), n)
expand.grid(l)
Comme alternative à l'approche de @ Justin, vous pouvez également utiliser CJ
à partir du package "data.table". Ici, j'ai également utilisé replicate
pour créer ma liste de 14 zéros et uns.
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
Il y a 16384 permutations possibles. Vous pouvez utiliser le package iterpc
pour récupérer le résultat de manière itérative.
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
Si vous voulez tous les résultats, vous pouvez toujours utiliser getall(I)
.
tidyr
a quelques options similaires à expand.grid()
.
tidyr::crossing()
renvoie un tibble et ne convertit pas les chaînes en facteurs (bien que vous puissiez faire expand.grid(..., stringsAsFactors = F)
).
library(tidyr)
crossing(var1 = 0:1, var2 = 0:1, var3 = 0:1)
# A tibble: 8 x 3
var1 var2 var3
<int> <int> <int>
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()
peut donner les deux combinaisons de seules valeurs qui apparaissent dans les données, comme ceci:
expand(mtcars, nesting(vs, cyl))
# A tibble: 5 x 2
vs cyl
<dbl> <dbl>
1 0 4
2 0 6
3 0 8
4 1 4
5 1 6
ou toutes les combinaisons possibles de deux variables, même s'il n'y a pas d'observation avec ces valeurs spécifiques dans les données dans les données, comme ceci:
expand(mtcars, vs, col)
# A tibble: 6 x 2
vs cyl
<dbl> <dbl>
1 0 4
2 0 6
3 0 8
4 1 4
5 1 6
6 1 8
(Vous pouvez voir qu'il n'y avait aucune observation dans les données d'origine où vs == 1 & cyl == 8)
tidyr::complete()
peut également être utilisé de la même façon que expand.grid()
. Ceci est un exemple de la documentation:
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
<dbl> <dbl> <chr> <int> <int>
1 1 1 a 1 4
2 1 2 b 3 6
3 2 1 a NA NA
4 2 2 b 2 5
Cela donne toutes les combinaisons possibles de item_id et item_name pour chaque groupe - cela crée une ligne pour le groupe 2 item_id 1 et item_name a.
Puisque vous avez affaire à des 0 et des 1, il semble naturel de penser aux entiers en termes de bits. En utilisant une fonction qui a été légèrement modifiée par rapport à cela post (MyIntToBit
ci-dessous), avec votre choix de fonctions apply
, nous pouvons obtenir le résultat souhaité.
MyIntToBit <- function(x, Dig) {
i <- 0L
string <- numeric(Dig)
while (x > 0) {
string[Dig - i] <- x %% 2L
x <- x %/% 2L
i <- i + 1L
}
string
}
Si vous voulez une liste, utilisez lapply
comme ceci:
lapply(0:(2^14 - 1), function(x) MyIntToBit(x,14))
Si vous préférez une matrice, sapply
fera l'affaire:
sapply(0:(2^14 - 1), function(x) MyIntToBit(x,14))
Voici des exemples de sorties:
> 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
Il s'agit d'une approche différente des réponses précédentes. Si vous avez besoin de toutes les combinaisons possibles de 14 valeurs de 1 et 0, c'est comme générer tous les nombres possibles de 0 à (2 ^ 14) -1 et en conserver la représentation binaire.
n <- 14
lapply(0:(2^n-1), FUN=function(x) head(as.integer(intToBits(x)),n))