Seite 1 von 1

Problem mit for Schleife

Verfasst: Di Mär 27, 2018 4:41 pm
von Koplino
Hallo,
habe problem mit einer for-Schleife:
Ich habe eine Stichprobe mit Zurücklegen aus den 12 Monaten des Jahres. Ich will jetzt wissen, wie oft bei meiner Stichprobe zwei gleiche Monate gezogen werden, wenn ich 6 mal ziehe. Dazu simuliere ich die Stichprobe sehr oft und zähle die Male, wo ein Monat zwei mal oder öfter gezogen wird.
So die Idee. Wenn ich mir aber eine Funktion schreibe, die mir die Anzahl der Treffer (= der Anzahl der Ziehungen, bei der ein Monat zwei mal oder öfter gezogen wird), bekomme ich 1 zurück, auch wenn ich bei dem data.frame mehr als 1 sehen kann. Wieso ? Hier der Code:

Code: Alles auswählen

z<-c("jan","feb","mar","apr","mai","juni","juli","aug","sept","okt","nov","dez")
sample(z,6,replace = TRUE,prob = c(0.077,0.077,0.077,0.077,0.077,
                                   0.077,0.10,0.10,0.10,0.077,0.077,0.077))

geb<- replicate(50, sample(z,6,replace = TRUE,prob = c(0.077,0.077,0.077,0.077,0.077,0.077,0.10,0.10,0.10,0.077,0.077,0.077)))

#Habe einen Wahrscheinlichkeitsvektor, da nicht alle Monate gleich wahrscheinlich sind.

anztreffer <- function(a){
  treffer=0
  for(i in 1:50){
   if(max(table(a[,i]))>=2){
     treffer=treffer + 1
  }
return(treffer)}}
Was stimmt hier nicht? Danke im Voraus.

Re: Problem mit for Schleife

Verfasst: Di Mär 27, 2018 8:36 pm
von jogo
Hallo Koplino,

willkommen im Forum!
Es ist immer etwas schwierig, sich in fremde Quelltexte einzuarbeiten, wenn diese unkommentiert sind.
Meistens ist für jemanden, der gleiches programmieren möchte ein komplettes Neuprogrammieren wesentlich einfacher.
Etwas stutzig machten mich die Wahrscheinlichkeiten für die Monate; diese entsprechen nicht dem üblichen Auftreten:

Code: Alles auswählen

#> c(31, 28, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31)/365
# [1] 0.08493151 0.07671233 0.08493151 0.08219178 0.08493151 0.08219178 0.08493151 0.08493151
# [9] 0.08219178 0.08493151 0.08219178 0.08493151
Die von Dir angegebenen Wahrscheinlichkeiten ergeben in der Summe weniger als 100%

Code: Alles auswählen

#> sum(c(0.077,0.077,0.077,0.077,0.077,0.077,0.10,0.10,0.10,0.077,0.077,0.077))
#[1] 0.993
Welche Bewandnis hat es damit?

Die Verwendung von replicate() ist gut. Allerdings würde ich bei der Testroutine eine schreiben, die eine einzelne Ziehung testet und dabei TRUE oder FALSE zurückliefert. Um die Gesamtheit der Ziehungen die Auswertung durchzuführen, kann man apply() über die Datenmatrix jagen.

Hier schon mal das Kernstück der Programmierung:

Code: Alles auswählen

z <- c("jan","feb","mar","apr","mai","juni","juli","aug","sept","okt","nov","dez")
s <- sample(z, 6, replace=TRUE, prob=c(31, 28, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31)/365)
any(table(s)>1) ### Auswertung für ein sample
So, jetzt habe ich Deinen Code analysiert:
soweit sieht er nicht schlecht aus - nur ein kleiner Fehler mit großer Wirkung:
das return(...) steht etwas zu früh. Es muss als letztes stehen vor der geschweiften Klammer, die die Funktionsdefinition abschließt.
Also:

Code: Alles auswählen

anztreffer <- function(a){
  treffer=0
  for(i in 1:50) {
    if(max(table(a[,i]))>=2){
      treffer=treffer + 1
    }
  }
  return(treffer)
}

anztreffer(geb)
Noch eine Anmerkung zu der Art des Programmierens:
Es ist besser, wenn die Funktion die Datenmenge nicht kennen muss. Stell Dir vor Du möchtest nicht nur 50 Ziehungen durchführen sondern 500. Du müsstest bei Deiner Variante nicht nur bei der Generation der Daten die Anzahl ändern sondern Du müsstest in Deiner Funktion die for-Schleife ändern: for (i in 1:500)
Hier wäre for (i in 1:ncol(a)) besser (weil robuster).

Meine Variante sieht inzwischen so aus:

Code: Alles auswählen

z <- c("jan","feb","mar","apr","mai","juni","juli","aug","sept","okt","nov","dez")

testSample <- function() {
  s <- sample(z, 6, replace=TRUE, prob=c(31, 28, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31)/365)
  any(table(s)>1) ### Auswertung für ein sample
}
sum(replicate(50, testSample()))
Gruß, Jörg