Échantillon de n lignes aléatoires par groupe, dans un dataframe
À partir de ces questions - Échantillon aléatoire de lignes de sous-ensemble de R dataframe & Échantillon aléatoire de lignes dans dataframe je peux facilement voir comment au hasard de l'échantillon (sélectionner) 'n' lignes à partir d'une df, ou 'n' lignes qui proviennent d'un niveau spécifique d'un facteur à l'intérieur d'une df.
Voici quelques exemples de données:
df <- data.frame(matrix(rnorm(80), nrow=40))
df$color <- rep(c("blue", "red", "yellow", "pink"), each=10)
df[sample(nrow(df), 3), ] #samples 3 random rows from df, without replacement.
Pour par exemple un échantillon de 3 lignes aléatoires à partir de 'rose' de couleur à l'aide de library(kimisc)
:
library(kimisc)
sample.rows(subset(df, color == "pink"), 3)
ou de l'écriture de fonction personnalisée:
sample.df <- function(df, n) df[sample(nrow(df), n), , drop = FALSE]
sample.df(subset(df, color == "pink"), 3)
Cependant, je veux de l'échantillon 3 (ou n) lignes aléatoires de chaque niveau du facteur. I. e. le nouveau df aurait 12 lignes (de 3 bleues, 3 rouges, 3 jaunes, 3 de rose). Il est évidemment possible d'exécuter plusieurs fois, de créer newdfs pour chaque couleur, puis les lier ensemble, mais je suis à la recherche d'une solution plus simple.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez attribuer un ID aléatoire à chaque élément qui a un facteur en particulier le niveau de l'aide
ave
. Ensuite, vous pouvez sélectionner tous les Id aléatoire dans une certaine plage.Cela a l'avantage de préserver la ligne d'origine de l'ordre et les noms de lignes si c'est quelque chose qui vous intéresse. De Plus, vous pouvez ré-utiliser le
rndid
vecteur de créer des sous-ensemble de différentes longueurs assez facilement.rndid<=10
) et un groupe de seulement 3, toutes les trois lignes pour que le groupe sera retourné et pas de valeurs manquantes seront introduites ni d'échantillonnage être fait avec le remplacement. Donc, vous pouvez vous retrouver avec déséquilibrée groupes.at least
5 cas dans chaque groupe, comment puis-je faire cela à l'aide de votre solution?Dans les versions de
dplyr
0,3 et plus tard, cela fonctionne bien:Les anciennes versions de
dplyr
(version <= 0.2)J'ai décidé de répondre à cette aide dplyr, en supposant que ce serait le travail:
Mais il s'avère que dans 0,2
sample_n.grouped_df
S3 méthode existe, mais n'est pas enregistré dans l'espace de NOMS de fichiers, de sorte qu'il n'est jamais distribué. Au lieu de cela, j'ai dû le faire:Vraisemblablement ce sera corrigé dans une future mise à jour.
dplyr
utilisez-vous? Est-ce tronc?dplyr 0.3
cela fonctionne comme un charme. C'est ma façon préférée de faire le problème ci-dessus maintenant.%>%
transmet les résultats de chaque étape de l'avant à la fonction suivante, donc il n'y a pas besoin de "regarder en arrière". Exécuterx <- mtcars %>% group_by(cyl)
et puis commencer àx
. Vous verrez qu'il a une nouvelle attributs de classe, avec beaucoup d'autres (attributes(x)
), de sorte que toute fonction ultérieure "sait" qu'il ne traite qu'avec des données groupées cadre.dplyr
fonctions auront S3 méthodes spécifiques pourgrouped_df
objets. Voirmethods(sample_n)
.Je considère mon
stratifié
function, qui est actuellement hébergé comme un GitHub Gist.L'obtenir avec:
Et l'utiliser avec:
Il y a plusieurs différentes fonctionnalités qui sont utiles pour l'échantillonnage stratifié. Par exemple, vous pouvez également prendre un échantillon sorte de "à la volée".
Pour vous donner une idée de ce que la fonction n', voici les arguments pour
stratified
:df
: L'entréedata.frame
group
: Un caractère vectoriel de la ou les colonnes qui composent la "strates".size
: Échantillon d'une taille.size
est une valeur inférieure à 1, une quote-prélèvement de l'échantillon de chaque strate.size
est un entier de 1 ou plus, le nombre d'échantillons prélevés à partir de chaque strate.size
est un vecteur d'entiers, le nombre spécifié d'échantillons est prise pour chaque strate. Il est recommandé que vous utilisez un nommé vecteur. Par exemple, si vous avez deux strates, "A" et "B", et que vous vouliez 5 échantillons "A" et 10 "B", vous devez entrersize = c(A = 5, B = 10)
.select
: Cela vous permet de créer un sous-ensemble des groupes dans le processus d'échantillonnage. C'est unlist
. Par exemple, si votregroup
variable "Groupe", et il contenait trois strates, "A", "B" et "C", mais vous ne voulait échantillon de "A" et "C", vous pouvez utiliserselect = list(Group = c("A", "C"))
.replace
: Pour l'échantillonnage avec remplacement.source_gist("https://gist.github.com/mrdwab/6424112", filename = "stratified.R")
Voici une solution. Nous nous sommes séparés d'un ensemble de données.cadre dans les groupes de couleur. Puis nous avons échantillon de 3 lignes de chaque groupe. Cela donne une liste de données.les cadres.
À obtenir le résultat souhaité, nous fusionner la liste de données.des images dans 1 de données.cadre:
3
est fixé pour chaque groupe, mais je veux des valeurs différentes pour le groupe de sagesblue
j'ai besoin de2
,pink
j'ai besoin de1
,red
j'ai besoin de5
,enfin pouryellow
j'ai besoin de 3.3
avec c(2,1,5,3), mais il considère le premier élément que j'ai.e,2
Ici est une façon, à la base, qui permet de multiples groupes et d'échantillonnage avec remplacement:
Pour ajouter un autre groupe, de l'inclure dans les "par des' argument de l'agrégat.