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.
É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
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")
times
est le nombre de matrices aléatoires que vous voulez, ici 99burnin
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.thin
dit seulement faire un tirage au sort toutes les thin
échangesmtype = "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.
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
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
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),]
É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