Écrivons une première version naïve, toute simple mais qui renvoie les résultats proprement avec une dataframe.
new_population <- function(nb_couples = 100) {
girls = 0
boys = 0
for(i in 1:nb_couples) {
if(runif(1) > 0.5) {
boys <- boys + 1
} else {
girls <- girls + 1
if(runif(1) > 0.5) {
boys <- boys + 1
} else {
girls <- girls + 1
}
}
}
data.frame(girls,boys)
}
new_population(1000)
## girls boys
## 1 792 740
On peut aussi faire une version où on a le détail de la population.
new_population_detailed <- function(nb_couples = 100) {
df=data.frame();
for(i in 1:nb_couples) {
girls = 0
boys = 0
if(runif(1) > 0.5) {
boys <- boys + 1
} else {
girls <- girls + 1
if(runif(1) > 0.5) {
boys <- boys + 1
} else {
girls <- girls + 1
}
}
df=rbind(df,data.frame(girls,boys))
}
df
}
pop=new_population_detailed(1000)
Dans ce cas, on a accès au détail:
head(pop);
## girls boys
## 1 1 1
## 2 0 1
## 3 0 1
## 4 2 0
## 5 2 0
## 6 0 1
Et si on veut le nombre total d’enfants de chaque sexe:
sum(pop$boys)
## [1] 774
sum(pop$girls)
## [1] 690
Au fait, une façon d’écrire ça, “à la R” pourrait être
new_population2 <- function(n = 100) {
x <- floor(2*runif(n))
y <- floor(2*runif(n))
data.frame(girls=sum(1-x) + sum((1-x)*(1-y)), boys = sum(x) + sum((1-x)*y))
}
new_population2(1000)
## girls boys
## 1 767 739
Étonamment, c’est au moins 10 fois plus rapide mais également assez illisible donc à manier avec précaution.
Bref, dans tous les cas, vous vous rendez vite compte que quand n=100, il peut y avoir beaucoup plus de filles que de garçons ou l’inverse. Pour n=1000, l’écart se resserre. Et donc, le taux de masculinité tend vers ?…
p <- new_population2(2000)
p$boys/(p$boys+p$girls)
## [1] 0.4869
Surprenant, non ?
Mmmh, mais ça change à chaque fois donc comment être sûr. Visualisons celà en regardant par exemple la distribution expérimentale de la proportion de garçons…
pop_generate_dist <- function (nb_couples=100,n=200) {
df= data.frame()
for(i in 1:n) {
df = rbind(df,new_population2(nb_couples))
}
df$ratio = df$boys/(df$girls+df$boys)
df
}
hist(pop_generate_dist(nb_couples=2000)$ratio)
À partir de là, on peut voir plein de choses bizarres quand il y a peu de couples (nb_couples faible) ou qu’on ne fait que peu d’échantillons (n faible).
Allez, encore une variation sur le thème:
pop <- pop_generate_dist(nb_couples=2000)
plot(pop$girls,pop$boys)
Mmmh, mais que peut bien vouloir dire une telle représentation ? Qu’il y a une correlation entre le nombre de filles et le nombre de garçons ? Est-ce vraiment ce qui nous intéresse ? Bref, le choix de la représentation graphique est vraiment primordial dans l’analyse que l’on fait et dans le message que l’on souhaite passer.
Et au fait, la taille de la population ? Ça augmente, ça diminue, ça reste stable ?
population_init=2000
p <- new_population2(population_init)
(p$boys+p$girls)/(2*population_init)
## [1] 0.7492
Bon, et bien à vous de montrer que le taux de renouvellement est bien de 3/4…
new_population_repeat <- function(nb_couples = 100) {
girls = 0
boys = 0
for(i in 1:nb_couples) {
repeat {
x <- runif(1)
if(x>0.5) {
boys <- boys + 1
break
} else {
girls <- girls + 1
}
}
}
data.frame(girls,boys)
}
new_population_repeat(1000)
## girls boys
## 1 1000 1000
Bon et donc mêmes questions:
vers quoi converge le pourcentage de garçons ?
test_pop = 2000
p <- new_population_repeat(test_pop)
(p$boys)/(p$boys+p$girls)
## [1] 0.4988Et cette fois, la taille de la population ? Ça augmente, ça diminue, ça reste stable ?
(p$boys+p$girls)/(2*test_pop)
## [1] 1.002new_population_repeat <- function(nb_couples = 100, proba_no_child=.01, proba_girl=c(.5,.45,.4,.35,.3,.25,.2,.15,.1)) {
df=data.frame();
for(i in 1:nb_couples) {
girls = 0
boys = 0
x <- runif(1)
if(x>proba_no_child) {
for(p in proba_girl) {
x <- runif(1)
if(x<1-p) {
boys <- boys + 1;
break
} else {
girls <- girls + 1
}
}
}
df=rbind(df,data.frame(girls,boys))
}
df
}
pop = new_population_repeat(nb_couples = 1000)