2016-05-24 14 views
1

Ich versuche, drei etwa 100.000 Proben von Größe zu erzeugen, die von den Nummern 1 bis 20, ohne Ersatz, und verwendete den folgenden Code in R:Generieren von 100, 000 Proben von Größe drei von Zahlen 1 bis 20, ersatzlos

s <- sample(N,3,pi<-n*x/sum(x),replace=FALSE) 
[1] 12 6 17 

Jetzt gab mir eine Probe der Größe drei, aber wie generiere ich 100.000 von ihnen? Wir verwendeten auch

N<-20 #size of the population we could choose from 
n<- 3 
x <- runif(N) 
pi<-n*x/sum(x) 

aber ich weiß nicht, was schief gelaufen ist. Jeder Rat wird sehr geschätzt werden, danke.

+7

'replizieren (100000, Beispiel (1:20, 3), vereinfachen = FALSE)' – Khashaa

Antwort

2

Wir lapply verwenden können

N1 <- seq_len(100000) 
N <- 20 
lapply(N1, function(i) sample(N, size =3, replace=FALSE)) 
+0

Diese haben alle sehr nützlich sein. Danke Ihnen allen für Ihre Einsendungen. Chris Lilly. –

+0

@ChristopherBrentLilly Bitte denken Sie daran, die beste Lösung zu akzeptieren, indem Sie auf das Häkchen neben der Abstimmung klicken – akrun

4

Ihre Frage über eine Folge von looping inspirierte mich zu versuchen, eine Implementierung mehrerer Sampling-ohne-Ersatz Rekursion auf Probenahme- mit -Ersatz mit zu schreiben.

NS Letting repräsentieren die Anzahl der gewünschten Proben und NE die Anzahl der Elemente aus dem Eingangs für jede Probe eingestellt auszuwählen, meine Idee war, dass es von Vorteil sein könnte, um zu versuchen über NSsample() Anrufe zu vermeiden, Looping, welche Zeit sein würde, -Verbrauch für große . Stattdessen können wir einen einzelnen Beispielaufruf starten, der Werte mit Ersetzung nimmt, und betrachten, dass die "erste Auswahl" jedes Beispiels darstellen. Dann können wir für jede eindeutige Auswahl den Eingabesatz (und den Wahrscheinlichkeitsgewichtungsvektor) um das ausgewählte Element reduzieren und rekursiv ausführen, bis wir NE erreicht haben. Durch Kombinieren jedes (Teil-) Samples können wir eine Matrix erzeugen, deren Zeilen jeweils aus einem Sample ohne Ersetzung von NE Werten aus dem Eingangssatz bestehen.

samplesNoReplace <- function(NS,set,NE=length(set),prob=NULL) { 
    if (NE>1L) { 
     inds <- sample(seq_along(set),NS,T,prob); 
     uris <- split(seq_len(NS),inds); 
     us <- as.integer(names(uris)); 
     res <- base::matrix(set[inds],NS,NE); 
     for (ui in seq_along(uris)) { 
      u <- us[ui]; 
      ris <- uris[[ui]]; 
      res[ris,-1L] <- samplesNoReplace(length(ris),set[-u],NE-1L,prob[-u]); 
     }; ## end for 
    } else { 
     res <- base::matrix(sample(set,NS,T,if (length(set)==1L) NULL else prob),ncol=1L); 
    }; ## end if 
    res; 
}; ## end samplesNoReplace() 

Demo:

set.seed(10L); samplesNoReplace(10L,1:5,3L,c(10,2,2,2,1)); 
##  [,1] [,2] [,3] 
## [1,] 1 3 2 
## [2,] 1 4 3 
## [3,] 1 2 4 
## [4,] 3 2 1 
## [5,] 1 3 2 
## [6,] 1 4 2 
## [7,] 1 4 2 
## [8,] 1 2 5 
## [9,] 3 1 2 
## [10,] 1 2 5 

Benchmarking

library(microbenchmark); 

bgoldst <- function() samplesNoReplace(NS,set,NE,prob); 
akrun <- function() { N1 <- seq_len(NS); N <- length(set); lapply(N1, function(i) sample(set, size =NE, replace=FALSE,prob)); }; 
khashaa <- function() { replicate(NS, sample(set, NE,prob=prob), simplify = FALSE); }; 

## OP's case (100k samples, smallish set, smaller subset) 
set.seed(1L); 
NS <- 1e5L; set <- 1:20; NE <- 3L; prob <- runif(length(set)); 

microbenchmark(times=5L,bgoldst(),akrun(),khashaa()); 
## Unit: milliseconds 
##  expr  min  lq  mean median  uq  max neval 
## bgoldst() 40.9888 42.69257 46.33044 46.68856 47.40488 53.8774  5 
## akrun() 547.3142 564.94249 599.96134 625.07602 631.19658 631.2774  5 
## khashaa() 501.1226 521.14871 531.50227 524.65247 549.47600 561.1116  5 


## 1k samples, large set, large subset 
set.seed(1L); 
NS <- 1e3L; set <- 1:1000; NE <- 500L; prob <- runif(length(set)); 

microbenchmark(times=1L,bgoldst(),akrun(),khashaa()); 
## Unit: milliseconds 
##  expr  min   lq  mean  median   uq  max neval 
## bgoldst() 74478.4313 74478.4313 74478.4313 74478.4313 74478.4313 74478.4313  1 
## akrun() 350.7270 350.7270 350.7270 350.7270 350.7270 350.7270  1 
## khashaa() 353.2574 353.2574 353.2574 353.2574 353.2574 353.2574  1 

## 1M samples, small set, necessarily small subset 
set.seed(1L); 
NS <- 1e6L; set <- 1:4; NE <- 4L; prob <- runif(length(set)); 

microbenchmark(times=5L,bgoldst(),akrun(),khashaa()); 
## Unit: milliseconds 
##  expr  min  lq  mean median  uq  max neval 
## bgoldst() 502.0865 519.1875 602.5631 627.6124 648.3831 715.5459  5 
## akrun() 5450.3987 5653.0774 5817.0921 5799.4497 5987.0575 6195.4771  5 
## khashaa() 5301.3673 5667.8592 5683.3805 5744.1461 5824.8801 5878.6497  5 

## 10M samples, small set, necessarily small subset 
set.seed(1L); 
NS <- 1e7L; set <- 1:4; NE <- 4L; prob <- runif(length(set)); 

microbenchmark(times=1L,bgoldst(),akrun(),khashaa()); 
## Unit: seconds 
##  expr  min  lq  mean median  uq  max neval 
## bgoldst() 5.023389 5.023389 5.023389 5.023389 5.023389 5.023389  1 
## akrun() 75.891354 75.891354 75.891354 75.891354 75.891354 75.891354  1 
## khashaa() 69.422056 69.422056 69.422056 69.422056 69.422056 69.422056  1 

Das Muster ist sehr interessant und, glaube ich, leicht erklärlich. Meine Funktion übertrifft für viele Samples, kleine Sets und kleine Subsets, da nur sehr wenige Rekursionen erforderlich sind, um alle möglichen (Sub-) Sample-Zweige abzudecken, während die Looping-Lösungen iterieren und einen sample() Aufruf für jedes Sample machen müssen.Aber meine Funktion unterschreitet erheblich weniger Stichproben, große Mengen und große Untermengen, weil die Schleifenlösungen nicht sehr viele Iterationen zu vervollständigen haben, und der Baum der (Teil-) Stichprobenverzweigungen mit jeder neuen Auswahl etwas exponentiell wächst. Daher eignet sich meine Funktion nur für den Fall vieler Samples, kleiner Sets und kleiner Subsets, die übrigens ziemlich genau Ihren Beispiel-Anwendungsfall beschreiben.

Natürlich funktionieren die Looping-Lösungen selbst für ihre ungünstigsten Zeiten immer noch in einer Größenordnung meiner Funktion. Darüber hinaus ist es unwahrscheinlich, dass viele Millionen Proben einer kleinen Teilmenge einer kleinen Menge unter keinen Umständen benötigt werden. Aus Gründen der Einfachheit würde ich es daher nicht für unangemessen halten, diese Lösung vollständig zu ignorieren und immer den Schleifenansatz zu verwenden.

0

Ich habe sowohl den replicate-Befehl und die 1apply versucht, und beide geben mir 100.000 Proben der Größe drei für die Zahlen 1 bis 20, was gut ist, aber jetzt möchte ich zählen können, wie oft jede Zahl erscheint . Ich verstehe, dass 9 zum Beispiel potenziell 100.000 mal auftauchen könnte, wobei es sich um alle 100.000 3-Stichproben handelt, aber wahrscheinlicher ist, dass es etwa ein Zwanzigstel der Zeit auftreten könnte. Wenn ich also 100.000 Stichproben von 3 Ziffern pro Zeit habe, sollte die Gesamtzahl aller Zahlen bei 300.000 liegen, da R zum Beispiel Argumente für 100.000 Neunen gegeben hat, von denen 9 in jeder Stichprobe waren, dann sind noch zweihunderttausend übrig für alle anderen Zahlen. Ich habe die Funktion als s bezeichnet und versucht count1 < - Länge (die (s == 2)); count1, aber das sagte Fehler in dem (s == 1): (Liste) -Objekt kann nicht gezwungen werden, "doppelt", , aber ich verstehe nicht, was das bedeutet. Wie bitte ich R, mir eine genaue Zählung aller Einsen, aller Zweier usw. zu geben, wobei ich davon ausginge, dass ihre Gesamtsumme 300.000 betragen sollte, weil wir am Ende 300.000 Zahlen haben. Vielen Dank. Chris Lilly.