Vous pouvez échantillonner un nombre aléatoire de la séquence entière 1:n
, n
fois, mais exclure à chaque fois le numéro de cellule correspondant à la diagonale.
Une façon de faire est la suivante:
n <- 5
rnd <- sample(n-1, repl=T)
i <- c(rnd + (rnd >= seq_len(n-1)) * 1, sample(n-1, 1))
i
# [1] 3 3 4 5 1
Ici, chaque élément de i
est empêché d'être égal à l'indice de l'élément (par exemple, élément 1 ne peut pas être 1, élément 2 ne peut pas être 2, etc. .). Nous pouvons considérer chaque élément de i
comme la colonne sélectionnée pour chaque ligne à tour de rôle.
Ensuite, nous a mis en place une matrice de zéros, et (pour l'exemple ci-dessus) remplir les cellules [1, 3]
, [2, 3]
, [3, 4]
, [4, 5]
et [5, 1]
à 1.
m <- matrix(0, nc=n, nr=n)
m[cbind(seq_len(n), i)] <- 1
m
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 1 0 0
# [2,] 0 0 1 0 0
# [3,] 0 0 0 1 0
# [4,] 0 0 0 0 1
# [5,] 1 0 0 0 0
La dernière ligne de code utilise la matrice subsetting pour sous-ensembles de la matrice m
aux cellules pertinentes.
EDIT
Afin de faire en sorte que chaque colonne et chaque ligne ont une seule 1
, et que ceux-ci sont maintenus hors de la diagonale, l'approche vectorisé suivante fonctionne. L'astuce ici est de permuter le vecteur n-1
, et de considérer chaque élément de ce vecteur permuté comme l'indice, pour chaque ligne, des n-1
éléments non-diagonaux que nous affecterons 1
. Nous vérifions ensuite, pour chaque élément de notre vecteur permuté, si la valeur est inférieure à l'indice de la diagonale de la ligne correspondante. Si c'est le cas, nous laissons l'élément tel quel, sinon nous ajoutons 1. Cela détermine les indices de colonne pour les premières lignes n-1
. L'index de la dernière ligne est alors simplement l'index de la colonne qui n'a pas encore de 1
.
n <- 5
rnd <- sample(n-1)
i <- union(rnd + (rnd >= seq_len(n-1)) * 1, seq_len(n))
m <- matrix(0, nc=n, nr=n)
m[cbind(seq_len(n), i)] <- 1
m
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 1 0 0
# [2,] 0 0 0 0 1
# [3,] 0 0 0 1 0
# [4,] 1 0 0 0 0
# [5,] 0 1 0 0 0
Voulez-vous dire simplement que vous voulez un seul dans chaque rangée, mais pas sur la diagonale? – jbaums
Correct. C'est exactement le point. – JABalbuena
Ne voulez-vous pas aussi un '1' dans chaque colonne? Je vois que la réponse @jbaums ne conserve pas cette propriété. – flodel