 start recording. So welcome back everyone, also if you're watching this on Moodle, so like I said this is everything that there is to programming. So variables, for loops, if statements, and that's it. There's nothing more, no hidden mystery since a computer or a CPU can do anything else. And of course you just build this up and build this up. All right, so I've also done a little example, more or less on the slides. So for example, if we define a sequence from 2 to 100, stepping by 2, so we create a vector which I call even, and this vector now contains 2, 4, all the way to 100. If I want to add these all together, then I can just define a new variable which is called total, which will hold the sum of these numbers. And of course, before I started my loop, the sum will be zero. So I just put in zero. Then I say for number in even, and here the in vector, it's always for defining a new variable in and then a vector. And then what I do is I just say, well, every time that there's still a number in even, what do I want to do? Well, I take my total, I add the number to it, and then I save it in total. So what happens? Well, what happens is that first time that it's executed, the total is zero. So you get the sum total equals zero plus two. So then two is being stored in total. The next time it is total already has the value of two. So then I add the number four, which then goes to six. And then the six is now stored in total, then I add the six making 12, and so on. So it just goes through them. So it just loops and loops and loops. So if we talk about if statements or for loops, then there is something called a statement, and there is an expression. So the statement is the thing which evaluates to a logical value. So it evaluates to true or false, and it can only evaluate to true or false. Because in the if statement, if the statement does not evaluate to true or false, you will get an error or you will get a warning in R. And the thing which is between, litchi bones, thank you for following. So the thing that is between the curly brackets is called an expression. And of course, statements, the thing that you check for, can and will become very complex. Because in the end, if you're doing your own analysis, and then you, for example, imagine that you're doing a field research, and you have plans, and now you only want plans which are not diseased in a certain plot, which have a weight more than a certain amount of grams. So all of these things go into an if statement. And of course, you can say, well, not a. So if not the box equals to one, so it will test if the variable box is is is equal to one, and then the exclamation work will invert the statement. So everything that is true will become false, and the false will become true. You can also check two things at the same time. So I can make a statement saying that if the box is larger than one, and the box is smaller than 100, then do a certain expression. And of course, here, everything, the expression is only executed when the variable box contains a value from two to 99. Because of course, it's just smaller than and not smaller or equal. You can also do an or statement. So you can say, well, if the box is smaller than or equal to zero, or the box is larger than 100, then do the expression. So in this case, you have the logical and so both things need to be true. Here you have the or statement. So only this one needs to be true, or that one needs to be true. Of course, they can also both be true. Well, in this case, that's not possible, because there isn't a number which can be smaller than zero and at the same time by larger than 100. But the or statement is in a way that if this if the first part is true, or the second part is true, then the expression will be executed. And of course, you can you can loop this to infinity. So you can have like 60 different statements that you want to be true. And then all of these can be combined into a single is statement using the double ampersand. So we use the double ampersand here, which is very similar to the is is so the is equal to. And this is because we are dealing with single truths or false. So what kind of comparison operators are there in our well you have is is which means equal to you have question or exclamation mark is which means not equal to you have smaller than larger than smaller or equal to and larger or equal to. So we use this and end statement, right? So to to say if a and B are both through. So you also have a single ampersand and this works for vectors. The single a you also have the single or statement which also works for vectors. So it means that a single ampersand is vectorized and can be used for logical vectors. So if I don't do an if statement, right, and I just want to know if stuff which I put in V1. So in V1, I put the numbers one to five. And now I want to ask the question V1 smaller than four and V1 larger than two. And now you see false false true false false because only number three adheres to the fact that it is smaller than four and larger than two. The NN is not vectorized. So it takes the first element from a vector. So you have to make sure yourself that you only use it for single values and not for vectors. So just keep it in the back of your mind. If I want to do and if I want to compare if a number is larger than another number, I need to use the double statements. If I want to do stuff on vectors, then I have to use the singular singular or or the singular and so true and then false is is false. But if I have a vector which contains the value true and false, then if I do this, then it will more or less falsely say that this is true because it just takes the first element of the vector which is true and true is of course true. Is that clear? It will come back. It's especially handy when you are selecting from matrices to use the single single ands and ors. What do we ask with true and false? We just want to know if this statement is true. I write here true, but this would be x smaller than five and n something larger than 10. I can give you a little example. Let's go to Notepad++. Let me pull it up for myself. Imagine that I have a matrix. I will make a matrix. I will fill it with 100 random values between 0 and 1. Just from a uniform distribution, I will make a 10 by 10 matrix. Let's make it 20 rows, five columns. I call this m1. Now, if I want to use the... If I now want to know, if I would ask m1 at position 1, 1, so the first row, first column, if this value is smaller than 5 and m1, not 5, but 0.5, and m111 is, for example, larger than 0.2. Now, it could be that if in m11, it draws the value 0.1, then, of course, 0.1 is smaller than 0.5, but it is not larger than 0.2. Then this will evaluate to true and this will evaluate to false, making the whole statement false. When do you use the singular n's or or's? Let me pull up the R window and just define the matrix. I'm just going to copy that in. I'm just going to create a random matrix. I have matrix m1 and 20 rows. Imagine that I now want to select all of the rows which have a value which is larger than 0.1 in the first column. Then I can say, from matrix 1, get the first column. Then I ask the question, larger than 0.1. This will now give me a true, false, true, false vector. But now I want to have the measurement in column 2 to be, for example, smaller than 0.3. So I can say m1, larger than or matrix, column 1, larger than 0.1, and matrix 1, oh, sorry, that's the wrong one, and matrix 1, column 2 has to be smaller than 0.4, for example. Then now it gives me, again, a true, false statement vector. But now imagine that I only want to select the subset of the matrix of m1 for which these two things hold. Then I can just say, well, the nice thing about R is that you can use a true, false vector as the selection into a matrix. So I just say, sell, or select it. So I just define a variable, and this variable will now contain false, true, false, true, and so forth. And now I can say m1, and now give me the selected rows. And now you will see that in the first column of this sub matrix that I selected, the first column will always be higher than 0.1, and the second column will always be smaller than 0.4. And imagine now that instead of having a matrix with random numbers, you have your own kind of field research, or you have your own measurements that you did on mice or on fish, I want to select all of the fish which are male and have a weight which is less than half a kilogram. Then you can very easily, if you have thousands of measurements on fish, every row is a certain fish, then you very easily can select the ones which adhere to this statement. Is that clear? That this can be very useful when you want to kind of drill down on your whole data set and only select a subset. For example, females who are weighing more than 30 kilograms, or males which are younger than five years of age. So that's where this singular ampersand becomes really, really handy, or the singular or statement. So you can then select from the column which contains the sex, and you can select from the column which has the weights and the column which has the ages. And then you combine all of this into a single kind of statement, into a single true false vector, and then you can directly use that to select the subset of the matrix for which this holds. So in this case, there are six rows for which the first column is larger than 0.1, and the second column is smaller than 0.4. I hope that that's clear. And the if statements will come back a lot, because in the if statements you were it's more about controlling the flow of the program. So going left or going right or calling a different function. All right, let me move back as well. So just remember that the singular ampersand or the singular horizontal line is vectorized, while the double one is not vectorized and will only take the first element if you give it a vector. So in an if statement you need a single logical value, because the if statement asks if this is true, do that, otherwise do something else. So you never use the ampersand and the singular or in an if statement. And R will give you a warning message which looks like this. So if you do something if v1 or v1, then R will say, oh, you're doing something wrong. And the thing that you're doing wrong is that the condition has length more than one and only the first element will be used. So if you write your if statement wrongly and you use the vectorized operator, while you actually should use the non-vectorized operator, R will issue a warning message. And so if you see this warning message after writing an if statement, then check the statement within the if statement. And the statement probably is written wrongly with a singular, with a singular and or a singular or which means that it just vectorizes. Like I told you, you can do in vector comparison just like we just did in the matrix. And so you can use a logical vector as the index to a different vector. And so here I define a vector called 10 to one. So that just contains the numbers 10 to the number one. So 10, nine, eight, seven. And now I can say 10 to one smaller than five. And I can directly throw that back in into the 10 to one vector. So I can subset a vector, just like I can subset a matrix, which I just did. And so I can also do it a little bit differently. So I can also use a logical vector. Normally, when you do this right here, I get 10 answers. So because this statement just gives me 10 logical values back. However, I don't have to do that. You can also loop around, which sometimes can be very handy. For example, if I from this vector want to select the even numbers, then I can just say, well, I give a new vector, which has the length of two. And I say true false. So that would mean that it uses. So it just says 10 true, nine false, eight true, seven false, and so on. And then of course, when I do a subset like this, then it will select the even numbers. So it's the same thing as doing the sequence function, but it will loop around. So normally, you would want to not do this, because it's a little bit unclear what happens. But sometimes it's very useful to do something like this. And I generally use it when I'm selecting colors. Because then I have, for example, six colors, and I have like three groups, and then I use it to select the colors from a vector. However, it's very useful to do the selections from a vector using a logical vector as the index. But make sure that your logical vector has the same length as the vector that you are selecting from. So generally, you use it like this. So you say 10 to one, from 10 to one, select the variable lower than five. So you can do very advanced selections, like I showed you with the matrix, like column one, column two, column three, and you can put all kinds of restraints on these columns. And you can you can do the pairwise and or the pairwise or so. Hey, if I do 10 to one, and I ask for all the values larger than three and smaller than seven, then it will tell you this. So for all of the, so for 10, it will be false. For nine, it will be false and so forth. And then I can take the subset. Generally, what I do is I define a variable for this logical vector. So I put the logical vector that I create in a variable called either subset or edx or edx s. So I store it in a variable. And then I take the subset using the variable. Because otherwise, if you put this whole thing into this statement, then the statement will become very, very big, especially if you're selecting for like four or five different, different parameters. So it works for matrices as well. I already showed you that, but that just as an example on the slide, so I can define a matrix m one, which contains the values one to nine. It's a three by three matrix. So it's a little bit smaller than the one that I just showed you. And now I can say, well, m one, so from m one, select the first column smaller than three, right? So those are only the one and two. And then I store this into a variable. And then I use this variable to select a subset of the matrix. And now the statement that I just did will apply. So the sub matrix, all of the values in the first column will be lower than three. I can do the same thing for the rows as well. So I can, I can say I can, I can select m m one. So from m one, take the first column, if it is equal to three, then I can just plug that in just the same way. So I can put restraints on the columns, but I can also put restraints on the rows. And of course, now when you are selecting a single thing, it automatically turns it into a vector, which sometimes is handy. Sometimes it's really annoying that it swaps. Because if you select two elements, you get a vector back. If you only select one element, or if you select two elements, you get a matrix back. If you select only one element, then you get a vector back. And that's a little bit annoying. Because generally you want to have when you have a statement, you want the statement to always give you back the same type. But it's just the way that it is. All right. So that's more or less everything that I first wanted to say about control structures. Remember there are some special control structures. So one of these special control structures is the warning. So for example, imagine that you're writing code. And at a certain point in your code, you want to do something. But the thing that you're doing is only valid if you have numbers which are larger than zero. Then you can issue a warning. So you can use the warning function to issue a warning to the user. So for example, hey, if you if you have some code, and then at a certain point, you expect the value of X to be larger than zero. But you can check if it is true. So if X is smaller than zero, then you can issue a warning. You can also do the same thing with an error. So a warning will just show a warning on the screen. A stop will stop the execution of the program. So this will go horribly wrong. So if you use the stop command, then it stops more or less dead in its tracks. And you get an error, the error is displayed. And then it stops the execution of the rest of the script. You can use the try catch, which is very, very advanced. I never or never, I almost never used try catches. But I just wanted to show you guys how a try catch expression looks like. So you can do a try catch of a certain expression. So the expression here is something that might fail, right? So for example, I want to take the logarithm of a number. But I can't take the logarithm of a negative number, because those are not defined, just like the square root of a negative number is not defined. So then you can have a function which is called error. A lunes arrow. Thank you for following. But you can have the error function. And then when an error occurs. So if you do take the negative logarithm, then it will just print a statement. So it will, it will catch the error, and it will swallow the error, allowing you to continue. The finally is always executed, no matter if there was an error or not. The finally statement, like the print hello is always executed. We will get back to try catches at a certain point, because they are very useful when you are doing t tests on a matrix. So imagine that you have a matrix, and you know that you can only execute a t test when you have a minimum of three values versus three values, right? If I have one value in the first group and two values in the second group, then you cannot do a t test. But if you have a matrix, which has like 10,000 rows, right? And for each row of this matrix, you want to do a t test between like the first five samples, and the second five samples. If there are missing values, then it might be that at line 4000, or at row 4000 of your matrix, an error is generated. And at that point, it just stops the execution at line 4000. So you don't get all of your t test back. It might be that like the lines underneath have enough measurements so that you can do the t test. So the try catch allows you to continue after an error occurred. But you have to be very careful when you do that. But I just wanted to show you that because we're talking about control structures. And the try catch is one of the special control structures which allows you to recover from errors or recover from situations where it might not be entirely correct what you are doing. All right. So variables and control structures, this is an overview slide. So when we defy call one lower three from matrix, R does not only create the variable, but also kind of marks the elements in the matrix. No, no, it just gives you a true false vector. And you can use the true false vector to select from a matrix. So what R kind of does, I have the board here. So let me see if I can use that later on. But what R does is that if you have, let's switch back to R, right? Because this is kind of, so here you can see selected, right? So selected is the same as what we did before. So we have this matrix. And then for each of the elements in column one, I test to see if they're larger than 0.1. And I test if at the same time, the value in column two is smaller than 0.4. So if I look at this variable, selected, then selected is nothing more than false and true 20 times. And what it now does when I do M one, selected, it just looks to see if selected is true and then continue or then keeps this row. So it removes all the rows, which are false. So the first row is false. So it drops it from M one. The second row is true. So it keeps it in the output. The third one is also false. So that's dropped. The third one is kept, and so on. And you can see this more clearly when we add some row names to M one. So M one, if I say that the row names of M one is, for example, paste, like individual, and we have 20 rows, right? So if I look at M one, now it has row names, right? And now when we look at this selected value at selected, right, then it has false, true, false, true. So when I take M one, and I do selected, then now you can see that it keeps individual two, individual four, six, nine, 15, and 18. And those are exactly the positions at which selected is true. Is that clear, Giorgio? Perfect. Good. Let's continue. All right. So quick overview. Quick overview. So variables are boxes. They store things. Control structures manage program flow. So they do branching, if statements or switch statements. You can loop. So do something when, until a certain condition is reached, or do something an x number of times. And then we have warnings and errors. So warnings and errors are not something that, as a starting out programmer, you run into a lot. But in, in the end, when you get more advanced, you might want to issue a warning to yourself or an error to yourself, especially when you start reusing your code later on. So then it's good to have warnings and errors in there because you might write code now. And the code is only valid for numbers larger than 10. But in five years, you might not know this anymore. So then it's good that you put a warning in, so that in 10 years, hey, future, future you encounters the warning and thinks, oh, yeah, yeah, stuff has to be larger than 10, because otherwise my entire algorithm that I wrote won't work. All right. So advanced looping. So R provides another way of looping. And this has to do with multicore processors in a way. And it has to do with how memory is used in a computer. And there will be another lecture about using the L apply and the apply function. And we will go in much more detail then. So there's two functions in R, which do looping, but don't look like a loop. It's just a function call, right? So you have the L apply function, which takes X and then a fun. So the fun is the function that you want to execute on each element of X. So X here is a vector or a list. And what it will do, it will do this fun thing for each element of the list. So and the apply is the same thing, but apply works not on a vector or a list. But X here has to be a matrix or a data frame. And it repeats the function to each row or column in the matrix. And if you do if you want to do rows, or if you want to do columns, that is indicated by the margin here. So the margin is one, do it by the rows. Margin is two, do it by the columns. You can also specify margin is one and two. And then it will do rows and columns. Forget about the third one. I never used that ever, ever in like the 50 years that I've been programming R more or less. So I never use the margin is one, two. But one and two are very, very useful. And I will just quickly show you how you can use this in R. And then we will get back to it in a later lecture. So let's move to the R window, right? So we have this M one. So this is a matrix. So imagine that I want to calculate the mean of each row. I can write a for loop. So for x in one to the number of rows of matrix, blah, blah, blah, calculate the mean. So mean, you can calculate the mean by using the mean function. But it can also use this apply function. So I say apply to M one to the rows, the function mean. And now it will calculate for each row of the matrix, the mean. So it will calculate for individual one for individual two. If I want to have the rows, or instead of the rows, I want to have the columns, I can say, apply to this matrix to the columns, the mean function. And now it will give me five means. So for column one, column two, column three, column four, and column five. And this is really useful, right? Because you can say, well, apply the mean, I can also say, well, give me the standard deviation, or give me the median, right? So this is a, this is a perfect way of writing a one liner in case you want to get the mean, the median, or the standard deviation for a certain row or certain column in a matrix. The apply function works the same, but it works on a vector. So if I define a vector of one to 100, and I call this V one, then I can say apply to V one. And now what do I want to do for each element in the vector? Well, I want to, for example, say plus, and then I want to say 90. So what it will do, it will take this vector, which has a length of 100. So 100 items in there. And for each of these items, it will add 90 to it. So of course, head this will give you back a vector, a list, which at every point in the list, you have the original number plus 90. You can see that it gives you back a list, which is a little bit annoying. But the apply function is really, really useful for calculating row means or column means very, very quickly using a one liner. And of course, you don't have to use a prebuilt function. You can use your own function as well, which is really handy. But the structure is very basic. And the structure is very simply apply to the margin, margin one means rows, margin two means columns, a certain function. And then of course, you have these three dots. And that means that you can pass additional parameters to the function that you're executing. But we'll get to this in another lecture as well. So little example, we already did this. So I have a list at the first element of the list, I have 125. At the second element of the list, I have 123 and a missing value. And now I can calculate the mean for each element in my list. So I would say I'll apply my list mean. And then of course, the mean of the of the first list of 125 will be three. The mean of 123 and a missing value is a missing value, because missing values in our propagate, you cannot calculate the mean. When there is a missing value, well, you actually can and you have this additional parameter to the mean function, which is called na.rm, which is a parameter which allows you to ignore or remove missing values when you do the computation. So if I would say L apply, so apply to my list, the function mean ignore and a values when you encounter them, then now it will calculate and say, well, the first element of the list had a mean of three. The second, the second list in or the second vector in your list had a value of two. And you already see here that that I'm kind of grouping things together. So I am creating a list, the first element of the list is a vector. The second element of the list is also a vector. Same function but now apply. So if I have a matrix containing the values one to 50, 10 rows, five columns, then I can apply to the matrix one mean, so calculate the mean for each row or calculate the mean for each column. And I never use the C12. So just forget about that. So why would you want to use L apply or apply instead of just the standard for loop? They are much, much more efficient. And I say here sometimes, but sometimes means almost all of the time. So speed wise, they are very, very much more quick or they're, they're, they're a lot quicker than using a for loop. And this is because our can kind of assign the memory up front, because it knows that when I use an apply on a matrix, I will always get back a vector. So it can can already put the vector in place and then just fill in the numbers instead of having to expand memory has so and memory wise, they also work really, really well because they use less memory compared to the for loop or the while loop. One of the things that we already that that you should remember is that arithmetic function should be quoted. So if I want to do a plus or a minus or a divide or a power or something like that, then I have to put like the double quotes surrounding it. And that just has to do with the fact that if you wouldn't do that, then it are would get confused or the interpreter would get confused what you actually want to sum together. So only automatic function should be quoted a function like mean, you can just give the name of the function and it will work perfectly fine. But here, this is the same as when you want to get the help file for the plus function. Then you do question mark, and then between double quotes plus, and then it will open up the help file for addition. And the only reason why that is is because the plus is an infix operator while the mean is a prefix, but you can forget about that. We'll get back to that. But just remember that when you use L apply or use apply, you should quote, if you want to use an automatic function. All right, so L apply and apply will give you back a list. So if you want to get a vector, we already saw this when I was doing the analysis of the votes, you can use the unlist function to get a vector. So if I would do, if I would do this, right, I would L apply to the numbers one and two, the plus function, then it would give me back a list. The first element of the list contains six, the second element of the list contains seven. But in many cases, I want to get a vector back, and then I can use the unlist function to go from a list to a vector. And unlist is very, very powerful. And there's another lecture just about how to properly use the unlist function because you can do much more things with the unlist function and sometimes very, very useful things. So, but just remember that if you have a list, and you want to go to a vector, use unlist. All right, so then I want to complete the analogy because of course we have a third element. We have boxes, we have conveyor belts to move the boxes around. And then functions in my mind are factories. So if you have a factory, then in a factory, you have boxes, right, to do something with had these boxes are brought into the factory by means of parameters. Inside of the factory, you have control structures going left or going right or doing other things. But the nice thing about factories is that you can put a lot of boxes inside of the factory. But when you are outside of the factory, you cannot see these boxes. So they are not available to you. So you can kind of hide part of your code. And this is especially useful when you are defining variables like x or y, because you want to define them generally multiple times. You don't want to define x once and then use it all over. No, if you have a function that takes an input parameter, then this input parameter is not visible from the outside. And this concept of having a function and the variables inside of this function not being accessible from the outside is called scope. And that helps you to kind of encapsulate stuff. And this encapsulation makes code cleaner and allows you to just keep code separate from each other. So factories contain boxes and conveyor belts. There are some rules in R because in R, you have the rule that if you write a function, then you can input multiple boxes into that function. So you can have multiple parameters. So like the apply function, which has three parameters, right? The matrix, the function, and the margin. So the thing is, is inside of a function, you can also define your own variables called local variables. So you have function parameters, you have local variables. But in R, there's a restriction on what a factory can do. And the restriction on what a factory can do or what a function can do is that there's own, you're only allowed to return one box. That's it. No more, no two boxes, just one box, one variable can go and be returned to the outside of a function. So you define a function by using the special keyword called function. And then you can return a box using a special control statement, which is called return. So if I want to define a function, then I use the keyword function. And if I want to give back a box to the person that is using the function, then I can use the return statement. So a very basic function example, and we will get back to function. So don't worry too much if you don't understand what's happening exactly. But here we have a new variable being defined. So this new variable is called box factory. And this, this variable will contain a function. This function takes three parameters as input. So three input parameters, box one, box two, and box three. And then what will it do? Well, this function is largest, right? It is one, two, three, four, five, six, seven lines of code in there. But in the first line of the function, so the first thing what happens when you call the function box factory, it will do, it will define a new variable called fbox, which is a local variable. So this variable only exists within the function. And as soon as the function is done, it doesn't exist anymore. So what happens? Well, we define this new variable, we do some computation. So we subtract box two from box one and then multiply by block box three. Then we do a test. So if box one is smaller than box two, we return the first box. Else if, so in case box two is smaller than box three, then we return box two. If none of these two statements apply, we return the intermediate box. And we don't return the intermediate box itself, we return the value inside of the box. So this function that I show here, it has three function parameters. And it has one local variable, which is not visible from the outside. And functions help you to kind of structure your code and write very small reusable parts that you can use over and over again. So this is not very useful, because it doesn't really do anything mathematically sensible. But it's just to show you guys how a function is defined. A little bit of theory, since it's an introduction, and I want to tell a little bit of theory, also since I need some exam questions. And of course, I can have you program in the exam, or I can just ask you some questions about what you know. But these function parameters that get put into the function, they have three different, you can do that in three different ways. And R uses the third way, R uses pass by promise. But the first way that you can that you can give a box to a factory is pass by value. So that means that you instead of getting the box itself, you get a copy of the box. So you get only the value which is in the box, but not the box itself, which means that if you assign to the box inside of the function, it doesn't get changed. You have pass by reference, pass by reference means that function parameters are references. So you get the box. If you change the box within the function, then the value in the box will also change on the outside, which is sometimes really useful, but in many cases, not what you want as a beginning programmer. R is a mix of these two, R is pass by promise. And the reason why you have why this is important, what kind of how you pass these boxes around has to do with memory management. In the previous lecture, I told you that R has an issue with memory, because R is limited to how much memory there is in your computer. So of course, if I would use pass by value, then every time that I would call a function, and I would give it a big matrix, imagine a matrix with millions of rows and hundreds of columns, then every time this whole thing would get copied in memory, because the function gets called and it starts working on your big matrix. So it gets a copy. And that's not kind of what you want. So you have pass by value, which gives you the contents of the box. But this is a copy of the original stuff. You have pass by reference where you get the box. But then the issue is, is if you start modifying what's in the box, it will also appear modified outside of the function. And you have pass by promise, which is a mixture. And so you get references. And only when you start muddling with these references, so when you start overriding a value in this box, only then does it copy it. So it saves a lot of memory. All right, so R is pass by promise. So as a little example, if you update something, if you update a function parameter, it is not... Thank you for redeeming your award. Next slide. I will do the next slide in Dutch then, that will be interesting. Because I don't know how many people use Dutch. And I will of course do it in English as well, just to make sure that people can follow it. So in R, it's pass by promise. So updating them is not visible from the outside. And that's the thing that you have to remember. If you change a function parameter inside of a function, then it will not change the variable that you put in. So here I have a little example function. So this is a function which takes a single parameter. What it does, it takes the parameter, multiplies it by eight and then stores it into an internal variable. So in this case, P1 is still a reference. If then I take P2, right? So for example, I can put in the value five. So what happens is five gets multiplied by eight, leading to 40, which is put into P2. Then P2 gets added by five. So it's 45. And then this value gets assigned to P1. And P1 is the input variable. But the input variable is then reached, or the P1 is then returned, but it doesn't change it. So if I have a variable which has the value five, if I would call the function, then the function would return 45. But my var will still contain the value five. So it will not change. Is that clear? I think this is one of the most complicated concepts in programming is the pass by value, pass by reference, or pass by promise. I don't want you guys to know exactly what it is. I just want you to know that in R, when you give a variable to a function, this variable can never, ever change. And if you start doing things like this, where you are assigning something to the variable which is passed in, then this uses memory. So if you have a massive matrix that you give to a function, then as soon as you do this, as soon as you assign something to that variable, then the memory is copied. So instead of using five gigs of RAM, you all of a sudden use 10 gigs of RAM. And this is one of these things in R, which is really, really hard. Because especially when you start working with bigger datasets, you quickly run into the memory limits of R. Although it's not as pressing now anymore than it used to be. All right, next slide in Dutch. It's been a long time since I spoke in Dutch. Okay, so when we talk about functions, then we have functions default parameters. So a default parameter is a parameter that gives a function, which has a value that is logically chosen. So a, a, a best guess to put it simply. So when we have a variable, for something like an alpha level, in statistics testing, an alpha level is generally five percent. If we look at things like a false discovery rate, then a false discovery rate is generally ten percent. And these are biologically seen very logical values to choose. In other words, the field of field in science doesn't have to be like that. If we, for example, look at nature, a nature user uses an alpha level from five times ten to at least a third of something. So it's a much, much stricter alpha level. But in biology we have these alpha levels, and these alpha levels are the standard levels. Things like n-perms, the amount of permutations, so how often do we get something? In general, it also has a standard value. So a little example here. We define a variable called exp for exponent and we give that value five. We define a function called sum function and this has an imparameter, so it has an exponent. That exponent has a standard value of two. We can describe that, here we describe the standard value, but we can now call the function with one parameter instead of two parameters that we should normally specify. What it does is, as soon as we call the function, the first parameter is taken, which is made to the power exponent, is put up in a new internal variable. This internal variable is then returned to the outside world. If we call the function with only the value five, then it uses default, the standard value. If we call the function with two, then it uses the value that we give and we get five to the power five, which is 3,125 instead of 5, which is 5 to the power two. All right, you're happy, Testesaurus? Was it worth your 999 channel points? Good. We're going to take a short break. Totally, all right. We're going to take a short break. Another 10 minutes. So if you're completely lost at this point, don't worry. Don't worry at all. These are very complex concepts, but they will come back. When we come back in 10 minutes, I will redo this slide, the default parameter slide, and I will do it in Dutch. So just to make sure that everyone understands what the difference is between a default parameter and non-default parameter. Yeah, I'm going to do this one in English as well, but after the break, because it's four. So I have to stop the recording, because I've been recording for 50 minutes. All right, so then see you guys at 4.10, and the next break, I will stop the recording. The next break will...