knitr::opts_chunk$set(echo = FALSE)
library(ggplot2)
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
#### set up mutation 1/genome_size ####
# function only mutates a single bit
# if x is a vector with n>1 elements
# it will treat the whole vector as a bit
# it will not work
mutate <- function(x) {
p <- 1/(genome_size)
bit_flip <- rbinom(1, 1, prob = p)
x <- (x+bit_flip)%%2
}
#### set up reproduction with mutation ####
gametogeneis <- function(x) {
gamete <-c()
for (i in 1:nrow(x)) {
gamete <- rbind(gamete, sapply(x[i, ], FUN = mutate))
}
return(gamete)
}
#### generate 10 gametes for each individual
#### and randomly select from individual gametes ####
neut_select <- function(x) {
gamete <- list()
for (i in 1:gam_per_ind) {
gamete[[i]] <- (gametogeneis(x))
}
selection <- c()
for (k in 1:pop_size) {
selection <- rbind(selection,
gamete[[sample(1:gam_per_ind,1,T)]][sample(1:pop_size,1,T),]) #randomly select gamete for each individual
}
return(selection)
}
#### setup population, pop size, with genome size ####
#### consisting bits (0,1) ####
populate_binom <- function(pop_size, genome_size) {
N <- c()
for (i in 1:pop_size) {
N <- rbind(N,(rbinom(n = genome_size, size = 1, prob = 0.5)))
}
return(N)
}
### alternative ###
populate_sample <- function(pop_size, genome_size) {
N <- c()
for (i in 1:pop_size) {
N <- rbind(N,(sample(x = 0:1, size = genome_size, prob = c(0.5, 0.5), replace = T)))
}
return(N)
}
#### MAIN ####
genome_size <- 20
pop_size <- 100
gam_per_ind <- 10
generation <- 200
pop_test <- populate_sample(pop_size, genome_size)
rowSums(pop_test) # check fitness of initial population
## [1] 7 7 13 10 9 11 12 11 12 8 9 13 11 13 8 12 10 6 7 10 11 13 11
## [24] 10 13 9 9 10 10 11 14 12 12 9 13 10 9 12 8 11 8 10 12 10 13 14
## [47] 12 6 11 6 7 8 11 10 10 7 16 10 9 11 13 11 6 14 12 10 13 12 11
## [70] 11 7 10 10 12 8 11 14 12 8 9 11 8 9 9 12 8 13 9 9 10 13 11
## [93] 12 8 11 13 11 14 9 12
out_neutral <- data.frame(gen = 0, mean = mean(rowSums(pop_test))/genome_size,
min = min(rowSums(pop_test))/genome_size,
max = max(rowSums(pop_test))/genome_size)
##### preview fitness ####
out_neutral
which(rowSums(pop_test)/genome_size == max(rowSums(pop_test)/genome_size))
## [1] 57
pop_test[which(rowSums(pop_test)/genome_size == max(rowSums(pop_test)/genome_size)),]
## [1] 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1
which(rowSums(pop_test)/genome_size == min(rowSums(pop_test)/genome_size))
## [1] 18 48 50 63
pop_test[which(rowSums(pop_test)/genome_size == min(rowSums(pop_test)/genome_size)),]
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
## [1,] 1 0 0 1 1 0 1 0 0 0 0 0 0
## [2,] 0 0 0 1 0 1 0 0 0 1 0 1 0
## [3,] 0 0 0 0 0 0 0 0 1 0 0 1 0
## [4,] 0 0 0 0 0 0 1 0 1 0 1 0 0
## [,14] [,15] [,16] [,17] [,18] [,19] [,20]
## [1,] 0 1 0 0 0 0 1
## [2,] 0 0 1 0 1 0 0
## [3,] 0 1 1 0 1 0 1
## [4,] 1 1 0 0 0 1 0
counter <- 0
for (i in 1:generation) {
pop_test <- neut_select(pop_test)
counter <- counter + 1
out_neutral <- rbind(out_neutral, data.frame(gen = counter,
mean = mean(rowSums(pop_test))/genome_size,
min = min(rowSums(pop_test))/genome_size,
max = max(rowSums(pop_test))/genome_size))
}
head(out_neutral)
plot_neutral <- ggplot(out_neutral, aes(x = gen)) +
geom_line(aes(y = mean, colour = "mean")) +
geom_line(aes(y = max, colour = "max")) +
geom_line(aes(y = min, colour = "min")) +
coord_cartesian(ylim = c(0:10/10)) +
ggtitle("neutral") + xlab("generation") + ylab("fitness")
ggplotly(plot_neutral)