web-dev-qa-db-fra.com

Comment randomiser (ou permuter) une image par ligne et par colonne?

J'ai un dataframe (DF1) comme celui-ci.

     f1   f2   f3   f4   f5
d1   1    0    1    1    1  
d2   1    0    0    1    0
d3   0    0    0    1    1
d4   0    1    0    0    1

La colonne d1 ... d4 est le nom de fichier, la ligne f1 ... f5 est le nom de la colonne.

Pour faire un échantillon (df1), je reçois une nouvelle base de données avec un nombre égal à 1 identique à celui de df1. Ainsi, le nombre de 1 est conservé pour l'ensemble de la trame de données, mais pas pour chaque ligne ou chaque colonne.

Est-il possible de faire la randomisation par rangée ou par colonne?

Je veux randomiser le df1 colonne par colonne pour chaque colonne, c'est-à-dire que le nombre de 1 dans chaque colonne reste le même. et chaque colonne doit être changée au moins une fois. Par exemple, je peux avoir un df2 randomisé comme ceci: (A noté que le nombre de 1 dans chaque colonne reste le même mais que le nombre de 1 dans chaque ligne est différent.

     f1   f2   f3   f4   f5
d1   1    0    0    0    1  
d2   0    1    0    1    1
d3   1    0    0    1    1
d4   0    0    1    1    0

De même, je veux aussi randomiser le df1 par rangée pour chaque rangée, c’est-à-dire le non. La valeur 1 de chaque ligne reste la même et chaque ligne doit être modifiée (mais le nombre d'entrées modifiées peut être différent). Par exemple, un fichier DF3 randomisé pourrait ressembler à ceci:

     f1   f2   f3   f4   f5
d1   0    1    1    1    1  <- two entries are different
d2   0    0    1    0    1  <- four entries are different
d3   1    0    0    0    1  <- two entries are different
d4   0    0    1    0    1  <- two entries are different

PS. Merci beaucoup pour l'aide de Gavin Simpson, Joris Meys et Chase pour les réponses précédentes à ma question précédente sur la randomisation de deux colonnes.

71
a83

Étant donné le R data.frame:

> df1
  a b c
1 1 1 0
2 1 0 0
3 0 1 0
4 0 0 0

Shuffle par rangée:

> df2 <- df1[sample(nrow(df1)),]
> df2
  a b c
3 0 1 0
4 0 0 0
2 1 0 0
1 1 1 0

Par défaut, sample() réorganise de manière aléatoire les éléments passés en tant que premier argument. Cela signifie que la taille par défaut est la taille du tableau transmis. Passer le paramètre replace=FALSE (valeur par défaut) à sample(...) permet de s'assurer que l'échantillonnage est effectué sans remplacement, ce qui permet un brassage en ligne.

Mélangez les colonnes:

> df3 <- df1[,sample(ncol(df1))]
> df3
  c a b
1 0 1 1
2 0 1 0
3 0 0 1
4 0 0 0
202
pms

Jetez un coup d'œil à permatswap() dans le paquet vegan . Voici un exemple conservant les totaux des lignes et des colonnes, mais vous pouvez l'assouplir et corriger une seule somme de la ligne ou de la colonne.

mat <- matrix(c(1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1), ncol = 5)
set.seed(4)
out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")

Cela donne:

R> out$perm[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    1    1    1
[2,]    0    1    0    1    0
[3,]    0    0    0    1    1
[4,]    1    0    0    0    1
R> out$perm[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    1    1
[2,]    0    0    0    1    1
[3,]    1    0    0    1    0
[4,]    0    0    1    0    1

Pour expliquer l'appel:

out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
  1. times est le nombre de matrices aléatoires que vous voulez, ici 99
  2. burnin est le nombre de swaps effectués avant que nous commencions à prélever des échantillons aléatoires. Cela permet à la matrice d'échantillonnage que nous échantillonnons d'être assez aléatoire avant de commencer à prendre chacune de nos matrices randomisées.
  3. thin dit seulement faire un tirage au sort toutes les thin échanges
  4. mtype = "prab" indique que la matrice est traitée comme une présence/absence, c’est-à-dire des données binaires 0/1.

Quelques points à noter, cela ne garantit pas qu'une colonne ou une ligne a été randomisée, mais si burnin est assez long, il devrait y avoir de bonnes chances que cela se produise. Vous pouvez également dessiner plus de matrices aléatoires que nécessaire et éliminer celles qui ne correspondent pas à toutes vos exigences.

Votre exigence d'avoir différents nombres de modifications par ligne n'est pas couverte ici. Encore une fois, vous pouvez échantillonner plus de matrices que vous le souhaitez, puis éliminer celles qui ne répondent pas à cette exigence.

10
Gavin Simpson

C'est un autre moyen de mélanger le data.frame en utilisant le paquet dplyr:

rangée:

df2 <- slice(df1, sample(1:n()))

ou

df2 <- sample_frac(df1, 1L)

par colonne:

df2 <- select(df1, one_of(sample(names(df1)))) 

vous pouvez également utiliser la fonction randomizeMatrix dans le package R picante

exemple:

test <- matrix(c(1,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0),nrow=4,ncol=4)
> test
     [,1] [,2] [,3] [,4]
[1,]    1    0    1    0
[2,]    1    1    0    1
[3,]    0    0    0    0
[4,]    1    0    1    0

randomizeMatrix(test,null.model = "frequency",iterations = 1000)

     [,1] [,2] [,3] [,4]
[1,]    0    1    0    1
[2,]    1    0    0    0
[3,]    1    0    1    0
[4,]    1    0    1    0

randomizeMatrix(test,null.model = "richness",iterations = 1000)

     [,1] [,2] [,3] [,4]
[1,]    1    0    0    1
[2,]    1    1    0    1
[3,]    0    0    0    0
[4,]    1    0    1    0
> 

L'option null.model="frequency" conserve les sommes des colonnes et richness conserve les sommes des lignes . Bien que principalement utilisé pour la randomisation des jeux de données d'absence de présence d'espèces dans l'écologie des communautés, il fonctionne bien ici. 

Cette fonction propose également d’autres options de modèle nul. Pour plus de détails (page 36), reportez-vous au lien suivant: picante documentation

5
Anne Heloise Theo

Bien sûr, vous pouvez goûter chaque ligne:

sapply (1:4, function (row) df1[row,]<<-sample(df1[row,]))

mélangera les lignes elles-mêmes, de sorte que le nombre de 1 dans chaque ligne ne change pas. De petits changements et cela fonctionne aussi très bien avec les colonnes, mais ceci est un exercice pour le lecteur :-P

4
binfalse

Vous pouvez également "échantillonner" le même nombre d'éléments dans votre bloc de données avec quelque chose comme ceci:

nr<-dim(M)[1]
random_M = M[sample.int(nr),]
0
Marcos Pedrosa

Échantillons aléatoires et permutations dans une base de données S'il s'agit d'une matrice convertie en data.frame Utilisez la fonction sample du package de base Indexes = sample (1: nrow (df1), size = 1 * nrow (df1)) Échantillons aléatoires et permutations

0
thrinadhn