2017-03-10 1 views
2

Je souhaite prendre un site aléatoire pour chaque région, créer un nouveau bloc de données et répéter ces processus jusqu'à ce que tous les sites soient échantillonnés. Ainsi, chaque trame de données ne contiendra PAS le même site de la même région.Échantillon aléatoire par groupe, créer une nouvelle trame de données, répéter jusqu'à ce que toutes les entités d'un groupe soient échantillonnées

Quelques régions dans ma base de données réelles ont plus de sites (la région C a 4 sites) que les autres régions. Je veux supprimer ces lignes (peut-être que je devrais le faire avant de faire plusieurs trames de données).

Voici un exemple trame de données (réel a> 100 régions et> 10 sites par région):

mydf <- read.table(header = TRUE, text = 'V1 V2 Region Site 
5 1 A X1 
5 6 A X2 
8 9 A X3 
2 3 B X1 
3 1 B X2 
7 8 B X3 
1 2 C X1 
9 4 C X2 
4 5 C X3 
6 7 C X4') 

Repeating trois fois le code suivant produit des trames de données qui contient les mêmes sites pour une donnée Région (Les deuxième et troisième tables ont toutes deux le site X2 pour la région A).

do.call(rbind, lapply(split(mydf, mydf$Region), function(x) x[sample(nrow(x), 1), ])) 

    V1 V2 Region Site 
A 8 9  A X3 
B 2 3  B X1 
C 6 7  C X4 

V1 V2 Region Site 
A 5 6  A X2 
B 7 8  B X3 
C 9 4  C X2 

    V1 V2 Region Site 
A 5 6  A X2 
B 3 1  B X2 
C 6 7  C X4 

Pourriez-vous s'il vous plaît me aider à créer plusieurs trames de données de telle sorte que toutes les trames de données contiennent toutes les régions, mais chaque trame de données contient uniques combinaison région-site.

EDIT: Voici la sortie attendue. Pour produire ceux-ci, dans le premier échantillonnage, dessinez un site (ligne) au hasard de chaque région et faites une trame de données. Dans le deuxième échantillonnage, répétez le même processus mais le même site pour une région donnée ne peut pas être dessiné. Ce que je veux, ce sont des trames de données indépendantes qui contiennent une combinaison unique de région-site.

V1 V2 Region Site 
5 1 A X1 
7 8 B X3 
1 2 C X1 

V1 V2 Region Site 
5 6 A X2 
3 1 B X2 
4 5 C X3 

V1 V2 Region Site 
8 9 A X3 
2 3 B X1 
9 4 C X2 
+0

Les questions sur le codage R sont généralement hors sujet ici. Je pense que ce sera sur le sujet sur [SO]. Si vous attendez, nous pouvons essayer de le migrer là. – gung

+0

Nous sommes désolés. Merci d'essayer de le faire migrer. –

+0

Pourriez-vous montrer le résultat attendu? – akrun

Répondre

0

Le grand paquet data.table fait effectivement ce très facile

# Turn mydf into a data.table 
library(data.table) 
setDT(mydf) 

# Shuffle the rows of the table 
dt <- dt[sample(.N)] 

# In case there are multiple rows for a given Region <-> Site pair, 
# eliminate duplicates. 
dt <- unique(dt, by = c('Region', 'Site')) 

# Get the first sample from each region group 
# Note: .SD refers to the sub-tables after grouping by Region 
dt[, .SD[1], by=Region] 

# Get the second and third sample from each region group 
dt[, .SD[2], by=Region] 
dt[, .SD[3], by=Region] 

En fait, vous pouvez combiner en une seule ligne comme Frank a suggéré

library(data.table) 
dt <- setDT(mydf) 
dt <- unique(dt, by = c('Region', 'Site')) 
dt[sample(.N), .SD[1:3], by = Region] 
+0

L'étape "éliminer les doublons" peut également être effectuée avec 'unique'. En ce qui concerne la dernière partie, peut-être juste 'dt [, .SD [1: 3], by = Region]' puisque l'OP ne veut que trois sites par région. En guise de note, je pense que c'est une mauvaise pratique d'écraser 'dt <-' car il est plus difficile de déboguer. – Frank

+0

Mise en évidence de la clarté pour OP. Ajouté un one-liner aussi. – andrew

+0

Ok, joli doublure. Btw, juste pour clarifier. 'dt <- dt [...]' rend le code moins clair car si je veux comprendre à quoi ressemblait 'dt' avant une telle étape, je dois recommencer le code depuis le début. Plus simple serait 'newdt <- dt [...]'. Un point séparé: avec 'setDT', il n'y a pas besoin d'assigner. 'mydf' est devenu une table de données elle-même, modifiée par référence. – Frank

0

Il a fonctionné! Je ne vois pas de coche pour accepter la réponse, alors je fais ici.