SexOnR–06_Templates. Semi-finished components for building R models (R Reference II)
This page collects R script fragments that may be useful for constructing various types of models
Semi-finished products for creating R models The purpose of this page is simple: to collect fragments of R scripts here that can be useful when creating new models. What to call these fragments? Examples? Samples? Templates? 'Pre-made items'? Recipes? Let's call them 'semi-finished products'. The content of this page is ongoing; much remains unclear in this work (for example, it is not easy to decide in what order to arrange these semi-finished products). However, we hope that the result of this work will be useful for students learning this course. Currently, the following semi-finished products have been added: Getting Started. Reading and writing data files Creating an empty vector of a specific length Creating an empty matrix with named rows and columns Creating a group of random numbers Building a simple scatter plot (scatterplot) Building a line chart for three variables Calculating the correlation between two traits "Heatmap" of correlation between many traits Probabilistic rounding Forming a random sample using the sample() function Modeling selection using the sample() function and a "fate vector" Switch for multiple choices: switch() Iterating through initial parameter values Three-dimensional visualization of parameter search results Custom function for competitive population reduction (simulation at the group level) Population reduction due to selection (simulation at the individual level) Non-competitive simulation of population reduction (simulation at the individual level) Printing progress reports of calculations to the console Getting Started. Reading and writing data files Statistical research in R almost always begins with loading a data file; this step is not mandatory for modeling but can also be used. The first line of the provided script sets the working directory (where R will look for and create files). An example address used by the author for this course is given; of course, everyone else's address will be different (by the way, addresses for Windows are structured differently than for Linux). To offer R a data file in \*.csv format, it should be created in spreadsheet software (Excel, Calc, etc.). If a comma is used as the decimal separator (as is common on most computers in Ukraine), this should be explicitly stated.
setwd("~/!_Courses/Sex_on_R") # Робоча директорія (лише на комп'ютері Д.Ш.!!!)
rm(list = ls()) # Очищення середовища від збережених об'єктів (щоб попередні сесії роботи не заважали наступним)
Sam <- read.csv('Sample.csv', sep = ";", dec = ",") # Дані перенесені у об'єкт R
summary(Sam) # На створений об'єкт можна подивитися; ця команда виводить характеристики його стовпців
## X1 X2 X3 X4
## Min. : 2.00 Min. : 3.00 Min. : 4.00 Min. : 5.00
## 1st Qu.: 5.25 1st Qu.: 6.25 1st Qu.: 7.25 1st Qu.: 8.25
## Median : 8.50 Median : 9.50 Median :10.50 Median :11.50
## Mean : 8.50 Mean : 9.50 Mean :10.50 Mean :11.50
## 3rd Qu.:11.75 3rd Qu.:12.75 3rd Qu.:13.75 3rd Qu.:14.75
## Max. :15.00 Max. :16.00 Max. :17.00 Max. :18.00
## X5 X6
## Min. : 6.00 Min. : 7.00
## 1st Qu.: 9.25 1st Qu.:10.25
## Median :12.50 Median :13.50
## Mean :12.50 Mean :13.50
## 3rd Qu.:15.75 3rd Qu.:16.75
## Max. :19.00 Max. :20.00
save(Sam, file = "Sam.RData") # Збереження даних у форматі, що використовує R
load("Sam.RData") # Читання збереженого файлу з робочої директорії
Creating an empty vector of a specific length
amount <- 10
vect <- rep(NA, amount)
vect
## [1] NA NA NA NA NA NA NA NA NA NA
Creating an empty matrix with named rows and columns
rws <- c("One", "Two", "Three", "Four", "Five")
cls <- c("First", "Second", "Third", "Fourth", "Fifth", "Sixth")
mtrx <- matrix(NA, nrow = length(rws), ncol = length(cls), dimnames = list(rws, cls))
mtrx
## First Second Third Fourth Fifth Sixth
## One NA NA NA NA NA NA
## Two NA NA NA NA NA NA
## Three NA NA NA NA NA NA
## Four NA NA NA NA NA NA
## Five NA NA NA NA NA NA
Creating a group of random numbers
mtrx[, 1] <- runif(length(rws), 0, 10)
mtrx[, "Second"] <- runif(length(mtrx[, "Second"]), 1, 2)
mtrx
## First Second Third Fourth Fifth Sixth
## One 9.269929 1.072318 NA NA NA NA
## Two 7.516522 1.495302 NA NA NA NA
## Three 5.082234 1.143656 NA NA NA NA
## Four 1.627083 1.769866 NA NA NA NA
## Five 6.134429 1.685893 NA NA NA NA
Building a simple scatter plot (scatterplot)
plot(mtrx[, "First"], mtrx[, "Second"], main = "General scatterplot", xlab = "First axis", ylab = "Second axis")
Building a line chart for three variables First, let's create a matrix with the data to be visualized (the use of the sample() function is explained below).
mtr <- matrix(NA, 3, 20)
mtr[ , 1] <- sample(10:30, 3)
for (i in 2:20) {mtr[ , i] <- mtr[ , i-1] + sample(-2:2, 3)}
mtr
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,] 29 27 28 28 26 24 24 24 23 22 23 23 21 22
## [2,] 10 12 14 13 13 15 17 15 17 19 19 20 19 21
## [3,] 11 10 10 8 10 11 9 8 9 9 11 10 12 11
## [,15] [,16] [,17] [,18] [,19] [,20]
## [1,] 24 26 25 24 23 21
## [2,] 20 18 19 17 18 19
## [3,] 9 9 9 10 8 8
Now we can build the graph
plot(mtr[1, ], type="l", lty=2, col="red", # Перша лінія
main = "Line chart", # Заголовок
ylim = c(0, max(mtr)), # Масштаб осі ординат
xlab="First axis", ylab="Second axis") # Підписи осей
lines(mtr[2, ], type="l", lty=3, col="blue") # Друга лінія
lines(mtr[3, ], type="l", lty=4, col="green") # Третя лінія
legend(2, 10, inset=.05, title="Позначення:", c("Перша лініяі","Друга лінія", "Третя лінія"), # Легенда
lty=c(2, 3, 4), col=c("red", "blue", "green")) # Порівнювані елементи в легенді
// add bootstrap table styles to pandoc tables function bootstrapStylePandocTables() { $('tr.odd').parent('tbody').parent('table').addClass('table table-condensed'); } $(document).ready(function () { bootstrapStylePandocTables(); }); $(document).ready(function () { window.buildTabsets("TOC"); }); $(document).ready(function () { $('.tabset-dropdown > .nav-tabs > li').click(function () { $(this).parent().toggleClass('nav-tabs-open'); }); }); (function () { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; document.getElementsByTagName("head")[0].appendChild(script); })(); Calculating the correlation between two traits
cor.test(mtrx[ , "First"], mtrx[ , "Second"], method ="spearman")
##
## Spearman's rank correlation rho
##
## data: mtrx[, "First"] and mtrx[, "Second"]
## S = 14, p-value = 0.6833
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.3
Of course, you can specify method = “pearson” "Heatmap" of correlation between many traits First, let's fill the matrix columns with traits whose relationship makes sense to investigate.
mtrx[ , "Third"] <- mtrx[ , "First"] + mtrx[ , "Second"]
mtrx[ , "Fourth"] <- mtrx[ , "Third"] + runif(nrow(mtrx), 0, 1)
mtrx[ , "Fifth"] <- 2 + runif(length(mtrx[ , "Fifth"]), -1, 1)
mtrx[ , "Sixth"] <- mtrx[ , "Fifth"] + 1
mtrx
## First Second Third Fourth Fifth Sixth
## One 9.00222090 1.905020 10.907241 11.292740 1.114117 2.114117
## Two 2.79331013 1.490399 4.283709 5.099022 1.226960 2.226960
## Three 0.85959514 1.917520 2.777115 3.653694 1.684746 2.684746
## Four 0.82524304 1.340165 2.165408 2.436028 2.109354 3.109354
## Five 0.06033371 1.549691 1.610025 2.434575 2.896808 3.896808
Install (on first run) and download the necessary library
# install.packages("GGally")
library(GGally)
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
Build a "heat map"
ggcorr(mtrx)
Probabilistic rounding. You can use both the floor() and trunc() functions. A random variable uniformly distributed between 0 and 1 is added to the value to be probabilistically rounded; the sum is rounded down (for positive numbers) to the nearest integer. In the example provided, the average of 100 roundings of the value 3.3 should be sufficiently close to this value.
ProbabRound <- rep(NA, 1000)
for (i in 1:1000) {ProbabRound[i] <- floor(3.3 + runif(1))}
mean(ProbabRound)
## [1] 3.296
Generating a random sample using the sample() function. The sample(x, size, replace = FALSE, prob = NULL) function can be used both to generate sets of random integers and to select a certain number of objects from a population. The first two arguments are mandatory: x is the range from which the selection is made, and size is the sample size. The next two parameters are optional. If they are not specified, R uses the values provided in the sample full argument record. Thus, the replace parameter determines whether an element that has already been selected can be re-selected. In the case of replace = FALSE, after the first element is selected, the selected value is removed from those that can be selected in the next step. If replace=TRUE is specified, the command will select each subsequent element from the entire population.
sample(1:10, 9)
## [1] 2 9 7 8 4 1 3 6 5
# sample(1:10, 11) # Тут мало б бути повідомлення про помилку
sample(1:10, 11, replace=T) # Тут усе нормально: елементи можна обирати повторно
## [1] 6 2 8 1 9 4 3 1 6 9 7
Modeling selection using the sample() function and the "fate vector". The previous example shows a sample use of the sample() function. It can be used to model selection. Assume that the individuals listed in the Al_Pop vector are individuals against which selection s acts. The value of s ranges from 0 (all survive) to 1 (all die). Individuals in whose favor selection works survive completely in this case. Of course, non-competitive mortality, which thins out both types equally, can be as powerful as you like.
s <- sample(2:5, 1) / 10 # Випадково обирається значення добору
s
## [1] 0.4
Al_Pop <- sample(1:100, 12) # Сукупність, яка зазнає дії добору
Al_Pop
## [1] 37 47 56 49 15 27 35 65 74 82 62 4
Fate <- c(rep(NA, s*10), rep(1, (10-s*10))) # Вектор "долі"
Fate # (один на весь скрипт; він не є випадковим)
## [1] NA NA NA NA 1 1 1 1 1 1
Lot <- sample(Fate, length(Al_Pop), replace = T) # Вектор "жереба"
Lot # (створюється окремо для кожного скорочення)
## [1] NA NA NA 1 1 NA 1 NA 1 1 1 NA
Be_Pop <- Al_Pop * Lot # Скорочена сукупність; загиблі - NA
Be_Pop
## [1] NA NA NA 49 15 NA 35 NA 74 82 62 NA
Ga_Pop <- na.omit(Be_Pop) # Остаточно скорочена сукупність
Ga_Pop
## [1] 49 15 35 74 82 62
The switch() statement for multiple choices. Depending on the value taken by a certain variable (named Way in the example), certain actions should be taken. The switch() statement is used for this purpose. The Way variable should take values from the natural number sequence. If it takes values from a list, you can create a list of possible values and order it as shown at the beginning of the example.
Randoms = sample(10:99, 5)
Randoms
## [1] 27 32 63 93 56
Rando <- sort(unique(Randoms))
Rando
## [1] 27 32 56 63 93
x <- sample(Rando, 1)
x
## [1] 56
Way <- which(x == Rando)
switch(Way,
print(Rando[1]),
{print(Rando[2]); print("Second")},
{print(Rando[3]); (a <- x^2)},
print(Rando[4]),
print(Rando[5]))
## [1] 56
## [1] 3136
Iterating through initial parameter values. Used in Type III models
vector_First <- c(100, 200, 300, 400)
vector_Second <- c(0.1, 0.2, 0.3, 0.4, 0.5)
Outcome <- matrix(NA, nrow = length(vector_First), ncol = length(vector_Second), dimnames = list(vector_First, vector_Second))
for (a in 1:length(vector_First)){
First <- vector_First[a]
for (b in 1:length(vector_Second)){
Second <- vector_Second[b]
Outcome[a, b] <- First + Second * 100 # Тут розташовані основні розрахунки результату
}}
Outcome
## 0.1 0.2 0.3 0.4 0.5
## 100 110 120 130 140 150
## 200 210 220 230 240 250
## 300 310 320 330 340 350
## 400 410 420 430 440 450
Three-dimensional visualization of parameter iteration results. The Outcome matrix was generated in the previous example. It can be visualized as follows
# install.packages("plot3D")
library(plot3D)
persp3D(z = Outcome, x = vector_First, y = vector_Second, theta = 330, phi = 30,
zlab = "\nРезультат", xlab = "First", ylab = "Second",
expand = 0.6, facets = FALSE, scale = TRUE, ticktype = "detailed",nticks = 5, cex.axis=0.9,
clab = "Кольорова\nшкала", colkey = list(side = 2, length = 0.5))
Probabilistic rounding. You can use both the floor() and trunc() functions. A random variable uniformly distributed between 0 and 1 is added to the value to be probabilistically rounded; the sum is rounded down (for positive numbers) to the nearest integer. In the example provided, the average of 100 roundings of the value 3.3 should be sufficiently close to this value.
ProbabRound <- rep(NA, 1000)
for (i in 1:1000) {ProbabRound[i] <- floor(3.3 + runif(1))}
mean(ProbabRound)
## [1] 3.309
Generating a random sample using the sample function. The sample(x, size, replace = FALSE, prob = NULL) function can be used both to generate sets of random integers and to select a certain number of objects from a population. The first two arguments are mandatory: x is the range from which the selection is made, and size is the sample size. The next two parameters are optional. If they are not specified, R uses the values provided in the sample full argument record. Thus, the replace parameter determines whether an element that has already been selected can be re-selected. In the case of replace = FALSE, after the first element is selected, the selected value is removed from those that can be selected. If replace=TRUE is specified, the command will select each subsequent element from the entire population.
sample(1:10, 9)
## [1] 6 1 4 7 8 3 10 9 5
# sample(1:10, 11) # Тут мало б бути повідомлення про помилку
sample(1:10, 11, replace=T) # Тут усе нормально: елементи можна обирати повторно
## [1] 6 10 8 7 1 3 9 1 3 10 5
Modeling selection using the sample function and the "fate vector". The previous example shows a sample use of the sample() function. It can be used to model selection. Assume that the individuals listed in the Al_Pop vector are individuals against which selection s acts. The value of s ranges from 0 (all survive) to 1 (all die). Individuals in whose favor selection works survive completely in this case. Of course, non-competitive mortality, which thins out both types equally, can be as powerful as you like.
s <- sample(2:5, 1) / 10 # Випадково обирається значення добору
s
## [1] 0.2
Al_Pop <- sample(1:100, 12) # Сукупність, яка зазнає дії добору
Al_Pop
## [1] 10 49 46 74 89 65 67 80 7 31 14 25
Fate <- c(rep(NA, s*10), rep(1, (10-s*10))) # Вектор "долі"
Fate # (один на весь скрипт; він не є випадковим)
## [1] NA NA 1 1 1 1 1 1 1 1
Lot <- sample(Fate, length(Al_Pop), replace = T) # Вектор "жереба"
Lot # (створюється окремо для кожного скорочення)
## [1] NA 1 1 1 1 1 1 1 1 1 1 NA
Be_Pop <- Al_Pop * Lot # Скорочена сукупність; загиблі - NA
Be_Pop
## [1] NA 49 46 74 89 65 67 80 7 31 14 NA
Ga_Pop <- na.omit(Be_Pop) # Остаточно скорочена сукупність
Ga_Pop
## [1] 49 46 74 89 65 67 80 7 31 14
## attr(,"na.action")
## [1] 1 12
## attr(,"class")
## [1] "omit"
The switch() statement for multiple choices. Depending on the value taken by a certain variable (named Way in the example), certain actions should be taken. The switch() statement is used for this purpose. The Way variable should take values from the natural number sequence. If it takes values from a list, you can create a list of possible values and order it as shown at the beginning of the example.
Randoms = sample(10:99, 5)
Randoms
## [1] 85 47 43 93 26
Rando <- sort(unique(Randoms))
Rando
## [1] 26 43 47 85 93
x <- sample(Rando, 1)
x
## [1] 93
Way <- which(x == Rando)
switch(Way,
print(Rando[1]),
{print(Rando[2]); print("Second")},
{print(Rando[3]); (a <- x^2)},
print(Rando[4]),
print(Rando[5]))
## [1] 93
Iterating through initial parameter values. Used in Type III models
vector_First <- c(100, 200, 300, 400)
vector_Second <- c(0.1, 0.2, 0.3, 0.4, 0.5)
Outcome <- matrix(NA, nrow = length(vector_First), ncol = length(vector_Second), dimnames = list(vector_First, vector_Second))
for (a in 1:length(vector_First)){
First <- vector_First[a]
for (b in 1:length(vector_Second)){
Second <- vector_Second[b]
Outcome[a, b] <- First + Second * 100 # Тут розташовані основні розрахунки результату
}}
Outcome
## 0.1 0.2 0.3 0.4 0.5
## 100 110 120 130 140 150
## 200 210 220 230 240 250
## 300 310 320 330 340 350
## 400 410 420 430 440 450
Three-dimensional visualization of parameter iteration results. The Outcome matrix was generated in the previous example. It can be visualized as follows
# install.packages("plot3D")
library(plot3D)
persp3D(z = Outcome, x = vector_First, y = vector_Second, theta = 330, phi = 30, # Побудова графіку
zlab = "\nРезультат", xlab = "First", ylab = "Second",
expand = 0.6, facets = FALSE, scale = TRUE, ticktype = "detailed",nticks = 5, cex.axis=0.9,
clab = "Кольорова\nшкала", colkey = list(side = 2, length = 0.5))
Custom function for competitive population reduction (group-level simulation). The simulation model can work with a list of groups of individuals with their population sizes specified (group-level simulation) and with a list of individuals (individual-level simulation). Which option is optimal depends on the diversity of individuals. It is clear that if the diversity of individuals is low, and there are many identical individuals in the model population, the first option is optimal. The input consists of three objects: Capacity is the environmental carrying capacity. Amounts are the population sizes of the competing groups for Capacity, and Competitiveness is the competitiveness of these groups. The competitive reduction algorithm used is discussed in more detail here. The output is the new, reduced population sizes of the groups. Here are two options. The first (CompetitiveReduction0) is deterministic and will lead to the same result every time.
CompetitiveReduction0 <- function(Capacity, Amounts, Competitiveness){
RelativCompetit <- Competitiveness/max(Competitiveness); Quoted <- RelativCompetit * Amounts
Way <- ifelse(sum(Amounts) <= Capacity, 1, ifelse(sum(Quoted) >= Capacity, 2, 3))
Reduced <- switch(Way, # Defines a formula for calculations based on value Way
Amounts, # If Way==1
round(Quoted*Capacity/sum(Quoted)), # If Way==2, & on next row — if Way==3:
round(Amounts-(Amounts-Quoted)*(sum(Amounts)-Capacity)/(sum(Amounts)-sum(Quoted))) )}
The ideology of simulation modeling is better served by the probabilistic rounding option.
CompetitiveReduction <- function(Capacity, Amounts, Competitiveness){
RelativCompetit <- Competitiveness/max(Competitiveness); Quoted <- RelativCompetit * Amounts
Way <- ifelse(sum(Amounts) <= Capacity, 1, ifelse(sum(Quoted) >= Capacity, 2, 3))
Reduced <- switch(Way, # Defines a formula for calculations based on value Way
Amounts, # If Way==1
floor(Quoted*Capacity/sum(Quoted) + runif(1)), # If Way==2, & on next row — if Way==3:
floor(Amounts-(Amounts-Quoted)*(sum(Amounts)-Capacity)/(sum(Amounts)-sum(Quoted)) + runif(1)) )}
This population reduction satisfies two important conditions: 1) the total population size before reduction is reduced to a value corresponding to resource availability; 2) the population size of each group before competitive reduction Amounts[i] is reduced to a population size after competitive reduction Reduced[i] such that in each group, the proportion of individuals that survived competitive reduction is proportional to the competitiveness of the representatives of that group: Competitiveness[i]/max(Competitiveness). After the function is created, it can be used to recalculate the population size of the model population. Let's create an example. The competitiveness of different groups is given in the "Compet" column. Note that the most competitive group has a competitiveness of 1. If the set of competitiveness values is different, it can be proportionally changed so that the values for different groups are distributed in the range from 0 to 1. We will use the probabilistic option; to make it work the same way every time, we will use the set.seed() command, which sets a particular starting point (defined by a number) in the chain of events that lead to the generation of random (actually, pseudo-random) numbers.
set.seed(123456)
K <- 20
rws <- c("A", "B", "C", "D", "E", "F")
cls <- c("Codes", "Compet", "s", "Al", "Be")
ModelPop <- matrix(NA, nrow = length(rws), ncol = length(cls), dimnames = list(rws, cls))
ModelPop[, "Codes"] <- 1:6
ModelPop[, "Compet"] <- c(1, 0.9, 0.1, 0.8, 0.5, 0.4)
ModelPop[, "Al"] <- c(12, 20, 15, 6, 5, 2)
ModelPop[, "Be"] <- CompetitiveReduction(K, ModelPop[, "Al"], ModelPop[, "Compet"])
ModelPop
## Codes Compet s Al Be
## A 1 1.0 NA 12 6
## B 2 0.9 NA 20 9
## C 3 0.1 NA 15 1
## D 4 0.8 NA 6 3
## E 5 0.5 NA 5 2
## F 6 0.4 NA 2 1
sum(ModelPop[, "Be"])
## [1] 22
From the alpha composition of the population, we moved to the beta composition. Why doesn't the beta population size clearly match the environmental carrying capacity limit (22 individuals instead of 20)? This is a consequence of randomness in the implementation of the population reduction algorithm. Population reduction due to selection (individual-level simulation). We will use the same model population as in the previous case, but we will simulate population reduction not at the group level, but at the individual level. To simulate competition, we will use not the Compet value, which is proportional to the individual's survival chances, but the s parameter (selection coefficient). When s=0, selection does not hinder the existence of a particular form; at s=1, it completely destroys it.
ModelPop[, "s"] <- 1- ModelPop[, "Compet"]
Let's create a vector Al_Pop consisting of the codes of each individual separately.
Al_Pop <- c(rep(ModelPop[1, "Codes"], ModelPop[1, "Al"]),
rep(ModelPop[2, "Codes"], ModelPop[2, "Al"]),
rep(ModelPop[3, "Codes"], ModelPop[3, "Al"]),
rep(ModelPop[4, "Codes"], ModelPop[4, "Al"]),
rep(ModelPop[5, "Codes"], ModelPop[5, "Al"]),
rep(ModelPop[6, "Codes"], ModelPop[6, "Al"]))
Al_Pop
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3
## [39] 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 6 6
Now let's make the probability of death for each individual proportional to s. The option shown here (using a loop) is resource-intensive but more understandable.
Selection <- rep(NA, length(Al_Pop))
Randoms <- runif(length(Al_Pop), 0, 1)
for (n in 1:length(Al_Pop)) {Selection[n] <- ModelPop[which(ModelPop[, "Codes"]==Al_Pop[n]), "s"]}
Be_Pop <- Al_Pop * (floor(Randoms - Selection) + 1)
Be_Pop <- Be_Pop[-which(Be_Pop==0)]
Be_Pop
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 4 4 4 4 4
## [39] 5 5 5 5
table(Be_Pop)
## Be_Pop
## 1 2 3 4 5
## 12 19 1 6 4
length(Be_Pop)
## [1] 42
Why didn't the number of individuals reduce to K? Because only competitive population reduction was performed. If the beta population size exceeds the environmental carrying capacity limit, the next stage of reduction should be carried out: non-competitive reduction. Non-competitive simulation of population reduction (individual-level simulation). After competitive reduction has been carried out, the probability of death for each individual becomes the same. It should depend on the ratio of the beta population size to the environmental carrying capacity.
if(length(Be_Pop) > K) {
Randoms <- runif(length(Be_Pop), 0, 1)
Ga_Pop <- Be_Pop * (floor(Randoms - (length(Be_Pop)-K)/length(Be_Pop)) + 1)
Ga_Pop <- Ga_Pop[-which(Ga_Pop==0)] }
Ga_Pop
## [1] 1 1 1 1 2 2 2 2 2 2 2 2 4 4 5
table(Ga_Pop)
## Ga_Pop
## 1 2 4 5
## 4 8 2 1
length(Ga_Pop)
## [1] 15
Fewer individuals remained than should have. Randomness... Displaying progress reports in the console. If the model requires long calculations, the problem of uncertainty arises: is it working or not, will it finish soon, or in a few weeks? The fact is that after the model script is launched, nothing happens on the computer screen during the entire calculation time. The user is unsure: is the calculation in progress, or has the program simply "frozen"? Will the calculation finish quickly, or can it take days or weeks? Tools that demonstrate the progress of task execution help to overcome such uncertainty. Let's create a script that can run for a long time and apply a "four-story" loop to it. When the Cons indicator is small, the script runs quickly, but if this indicator is increased, for example, by an order of magnitude, the number (and time of calculations) will increase by four orders of magnitude. A print() command is inserted into the highest loop, which outputs the specified value to the console. We will send the paste() construct, which combines the arguments listed in parentheses separated by commas, to the output.
Cons <- 10
z <- 0
for (f in 1:Cons) {
print(paste(f, "from", Cons))
y <- 0
for (s in 1:Cons) {
x <- 0
for (t in 1:Cons) {
w <- 0
for (f in 1:Cons) {
w <- w + f}
x <- x + w}
y <- y + x}
z <- z + y}
## [1] "1 from 10"
## [1] "2 from 10"
## [1] "3 from 10"
## [1] "4 from 10"
## [1] "5 from 10"
## [1] "6 from 10"
## [1] "7 from 10"
## [1] "8 from 10"
## [1] "9 from 10"
## [1] "10 from 10"
z
## [1] 55000
You can output calculations in percentages (%, i.e., parts per hundred) or in per mille (‰), parts per thousand, because the necessary calculations can be inserted into the print(paste()) command.