 So welcome. Also everyone is watching it on YouTube or on Boodle. Welcome back I'm hoping that the quality is good enough. I've been dropping some massive frames, but We'll just continue and see see how it works out. So I'm hoping that it will be okay It's not too bad for you guys So common idioms common idioms are things which I use over and over and over again Which every time when I write code, I see a problem and for this problem I have a kind of default solution. It's kind of a Algorithm in a way, so standard little algorithm for standard little things So some snippets I use again and again Are snippets like this So one of the things that is a major pitfall when you are programming in R is the factor Messing up So when you want to go from a factor variable into a numeric variable You have to go via the character because otherwise it will re Number or relabel your factor levels and as a little example here, I have Three or four values right after value five ten eleven and five They are coded as characters and now when I make a factor as it when I Forced them to be a factor variable. What happens is is that internally R starts recoding them. So R just Orders them and starts recoding them to save memory For the factor variable because it knows that a factor can be mentioned like a hundred times or 200 times So instead of every time writing down the exact factor value It just internally couples a number to each entry that is in the factor The problem comes in when I do an ass numeric on it, right? When I do an ass numeric on a factor even though the factor has the levels five ten eleven and five The ass numeric of this factor will produce three one two and three So the five is coded internally as a three the ten is Internally coded as a one and eleven is internally coded as two If I want to get the real numerical values of the numerical representation of the class of the factor class I have to go via the ass character. So I take the factor I transform them or I force them to be characters and then I force them to be numeric And now I get the original values back So this is something that goes wrong a lot of the time in R where you are doing an ass factor And you then do an ass numeric on it and in the end it kind of destroys the data that is in the factor levels and You always have to go via character So in the back of your mind every time that you need to go from a factor variable to a numeric variable Make sure that you first go via character And this is just useful advice and a lot of code that I write has this as numeric as As numeric as character and then a factor as input just to prevent it relabeling them as three one two and three internal some other idioms creating an empty list I Do this a lot when I have a for loop right and I calculate different things and I want to store all of these things in a list So for example, I'm going through the rows of the matrix and for each row I calculate three or four values, which I then want to return in a list If I want to make an empty list then for some weird reason you have to use the factor function So the function is called list the function is called vector Then you have to specify that you want to have a list and then the amount of space in your list So that for example five spaces If you want to remove a single column from a matrix, I generally do it like this So if I have a matrix called M matrix Then of course I take all the rows, right? So just comma taking all the rows and then I do minus which the call names of matrix is is some color right, so I I generally Like removing columns by their name and not by their number Hey, of course, I could have just written minus seven and then it throw it throws away column number seven but if you do it like this it takes you a lot more typing but The advantage of it is that when you get a new data set and the order of the columns have changed Then it will automatically or it will still throw away the column with the name some column So it prevents or it makes your code more future proof So if you get a new version of a data set then just using this kind of a way of removing columns Will mean that you always remove the correct column Yeah, because often I get a data set two or three times and every time that I get the data set people added a column Or they remove the column and then of course throwing away column seven might not throw away the column that I intended to throw away If you want to remove multiple columns, you can do the exact same structure But now you instead of using is is you use the in function, right? So you say which call names of matrix are in the major are in the columns that I want to remove So for example column a b and c and then I just say minus which so have removed those from my matrix You can do is the same strategy also for rows But the idea behind it is that you you want to use the row names and the column names in Because a matrix can have row names and the kind of column names and these are very useful To remove things by column name or by row name Because there's no chance of new data set to additional columns and now I'm removing the wrong column in the whole analysis so it just future proves your code to be explicit say no I want to remove the row names of the matrix which are in these row names and then throw them away. So Just do minus bridge and this makes your code a lot clearer Instead of just saying minus one five and thirteen No one knows exactly what is happening But here and when you say no take the row names look up these and then remove them That is much clearer. So it just makes your code future proof. It looks good a lot of the times when people make tables or columns they do this in Excel and Often when we make tables for publication, you want to have a certain format that you are using so for example, you want to write everything in scientific format and you want to always have like a Times ten to the power of minus two there, right? Because some are ten to the minus five others are ten to the minus seven But if you have zero point zero one, you don't want it to be written zero point zero one three Because you want to have the same structure in the whole column Then you can use the format function to force numbers into a certain format So here we say take this number Write it down in scientific format and make sure that you always mention three digits So it's one point three five times ten to the minus two And this will just force the whole column to use the scientific layout You don't have to use it with a single number. You can also input a list of numbers or a vector of numbers You can also do it the other way around right if I have one point three five times ten to the minus eleven And I want to write it out with all of the zeros in front of it Then of course, I can just say turn off scientific mode and just do the format Of course, the number of digits are now specifying the number of digits that it takes from the original input and not It doesn't stop after two digits behind the column But the format function allows you to go from one format So from like scientific formatting of numbers to more or less non scientific formatting where you just list all of the zeros in front So just a useful tip the format function is there. It has more options as well So you can just check it out Using question mark format in R and then you get the help file and it shows you all kinds of different format things that you can do But it's generally very useful to to be able to go from one format to the other Some other common idioms that I use a lot is using string split with L apply So and this is something that we will see a lot also next week during the fishy data analysis because I like Chopping up things in little pieces and then selecting from these little pieces, right? So for example imagine that I have a vector which has three dates in there, right? So it's the third of January 2020 the first of March 1995 and then the 20th of January. Oh, so that they're the other way around their month day here What I can do is I can then use this format and say well if I have these numbers, right? Split them based on the minus symbol So what this does it goes through the whole vector and for every vector for every element in the vector It splits it into in this case three loose parts If I don't want to get for example the year part I can use the unlist function and the unlist function takes this special function, right? Because unlist first takes or if you use the L apply function on the thing that I just split right the L apply function has a special Function that you can use which is this select from function So it's kind of the square bracket which you normally use to select from a matrix So what I'm saying here is is apply to every element that I just split it, right? Because I split it three elements or I split three elements From a vector into three elements each but apply to the split it values to select from and then take the third element So this will take twenty twenty nineteen ninety five and nineteen seventy three So the years and then I can use the unlist function to Get rid of the fact that it is a list but this is a very common idiom where You're you're chopping up characters or a list of characters into loose substrings Or to split them by other things and then you want to select from these from this list Every time the third element from the list We can also get the months by just saying well To the split it values select from and then take the first element every time which will give us zero three zero one zero one We can also use grapple so Grap logical is a way to do partial string matching So if I want to see if the string 20 occurs into any of these Strings, right? Then I can do grapple 20 as factor and grapple will say well true for the first one because we see 20 here for the second one It will say false because there is no 20, but for the third one it will say true again Why because the day here is 20 So it will it will match to zero to the string and if it occurs It will return true if it doesn't occur it will return false If we don't want to have a true false vector Then we can of course say which and then it will say 1 comma 3 because the first element contains 20 and the third element also contains 20 You can also directly use the grep function. So the grep is The same but it's just the which grapple So it's just a convenience function Greple is just the logical vector. So it tells you true false true And grep will just tell you 1 and 3 so it is the exact same thing instead of using which greple You can directly use grep and it will be the same answer it's just a way of Asking the question is this number or is this sequence of characters anywhere in this List of things that we are looking at so the grep function really useful when you want to do subsets or when people are Very smart and they try to encode things into column names or in row names Which you should actually never do but if if you Sometimes people do right we we use for example the mouse ID underscore ht for hypothalamus mouse ID underscore gf for gonadal fat So then you could use the grep function with ht to see which of these kind of combined IDs are measured on So the grep function is really really useful when you want to do string matching When you want to see if one string partially occurs or if part of this this string contains the letters that you are looking for To combine this a little bit. This is more or less the function that I use a lot when I want to go to seasons and that is because in linear modeling You often want to control for seasons and not so much for months, right? Because there's no real difference between January and February But spring might be very different from summer So have if you're under northern hemisphere, then this is the way that spring summer fall and winter are coded So the thing is that my two season function is a function which has a single parameter as input Which is called x which is the vector of dates that is being inputted and then it has pos and pos is where are the The months right because I need to know if the months if it's month Year day or if it's day month year. I Just went offline. That is strange. That is strange Let me see Yeah, no connection dropped completely frames missed you to rendering Yeah, I can talk in internet. Oh, I've been up sick old days. Am I still here? No Help no Twitch Can people still hear me? No All right start streaming connecting Back or not Now I hear myself Anyone in chat. Am I still here? Yes. Oh good. Yay I had some internet issues. It just said oh massive drop of frames reconnecting reconnecting Okay, good. I'm still there. Good. Good. Good. All right Yeah, so let's just continue so this is the way that I now I'm watching myself Which is also a little bit weird and I'm listening to myself as well So had the way that I go from from seasons to months or from months to seasons It's just having this function which will just take a list or a vector updates And then I will tell it that Position one position two is because I can have day month year or month day year And then I can just specify on which position the months are in the in the vector And the way that I do it is just say well have used this string split L apply selects from the position so take the first the second or the third And then unlist them and then make them numeric because when I have numeric months I can compare them and what I do is I first make a empty return element so I say return is a repeat of the NA for as many months than I have so the length of months So if I have three improved items it will return three output items And then I say well when the months is larger than three or smaller than five then it's spring and the same for all the other ones and I use this a lot because often in linear modeling you want to include the Season because that is the thing that has an effect the effect is not being born in January or being born in February No, there's generally for mice or plants. There's a big difference if they are planted in spring Or if they are planted in the fall or in the winter So generally you you don't want to put in 12 Factors 12 months as factor, but you want to input four Seasons as a factor it also gives you more statistical power because instead of calculating 11 betas for each month so relative to January you're now just calculating three betas relative to spring So it gives you more statistical power as well to use seasons instead of using months if you want to calculate with dates and you don't want to do strange splitting There's also this as date function in our so that will do kind of the conversion for you You just give it a single string which has a date encoded in it and then you can specify the format saying that well, I have months I Have days and then I have years and the years Here's capitalized meaning that it uses the long format for a year because you could also just write 070920 And then you would have used here with a small letter. So then you would have used small a small Y If you have two date objects, you can now do mathematics with them So you can just subtract them from each other And then it will tell you the amount of days between the two different dates that were passed And of course you can also then say well how many months or years are between two days? So you can convert dates to real date objects. So our internally also has a date structure Which is different from a character or a factor and if you use as date It also allows you to make nicer plots because it knows that you have different dates So instead of using one two three four and plot them all behind each other It can kind of do a time scale on the x-axis when the x-axis or the values of the x-axis specified are date values Then it will use the date and it will calculate the distance between the dates properly Instead of just saying well one two three four five and just putting the points like that Dates also work with the sec function. So I can also say Have today which I can get by sys.date So here I get the current date from the R system and then I can make a sequence from today Length out is 10. So so go 10 Steps from today and every time step by one week So then it will give you the date. So it will tell you today is the 8th of July Next week is the 15th of July and then the week afterwards is the 22nd of July So hey, it will it will if you can make your own sequences For example, if you have measured mice or if you have measured plans on Certain dates of the year or if you're going to do measurements every week. You can also substitute and replace This is done by the g-sub function So imagine that you have a vector which is the quick brown fox A fox can be smarter than a wolf and the early bird catches the worms and the early fox gets the bird We can just say g-sub fox by cat And now what it will do it will take each of these Strings in the in the vector and it will replace every occurrence of fox by the word cat So g-sub very powerful tool to do global substitutions So saying that well instead of having fox written we want to have cat written So it's very very common to do to kind of quickly modify Your input data and I used it also in the fishy data set Because there for example in some years they coded some fish species using the asset And in some other years it was just written down with ss right so then you can say g-sub ss by asset or g-sub asset by ss So to just make sure that it's consistent between the different years and the different measurements that they've done So very powerful tool g-sub and you can also do matching So you can say only replace fox when it is at the beginning of the sentence or when it is at the end of the sentence And you can specify that as well using like these additional additional characters If you want to order a matrix, which is something that happens a lot you can use the order function So the order function takes for example if I want to order my matrix by the column some column I can just say order my matrix some column and then it tells me the ordering And then I can use the ordering As the index to the rows right because i'm sorting one column, which means that I get a new Order for each of the rows and then I can use the returned ordering to order my matrix in ascending or descending And you can specify that in the order function. So the order function has an additional parameter called By and you can set by to being ascending or descending and then it will sort them in the order that you want Another very common idiom, which we use a lot is going through a matrix and collect multiple statistics, right? For example, I want to know for each row. What is the mean and what is the standard deviation? Well The way to do this and we've seen this already a couple of times is to first create an empty variable Which will hold the results. So I'm saying results is an empty variable What am I going to do? Well for x in one to the number of rows of the matrix So I'm just going to go and have a new variable called x first time It's one for the first row second time it's second it's two for the second row So what I'm going to do? Well, I'm going to calculate two things, right? So the mean and the standard deviation using the mean and standard deviation function And then I'm going to say well the results that I have are now A row bind because have bind a new row to the results And the row that I want to bind is the mean and the standard deviation So I'm just going to combine mean and standard deviation together From being two separate values into one vector, which is a length of two And then I'm going to bind this vector to my results So now of course the results will be in the exact same order as the rows of my matrix And have for the first row on the first row of results I will have the mean and the standard deviation that I can use So very common strategy Before you do anything make an empty variable Then do the for loop I want to do for every row of the matrix So for x in one to the number of rows of matrix Compute the things that you want to compute then combine them together using the c function And then use the row bind to remember that these two values were computed for row number one for row number two Another very common Um Idiom is I have a data frame And I want to do linear regression And the issue is is that This data frame some of the columns are characters. Some columns are numeric values and some columns are factors So what if I want to make sure that they are numeric? Well, what I always kind of do when I have a data frame in which some of the columns might be numeric Some other columns might not be numeric. Um, I always use this system where I say well take the columns that I want One through five for example or one two six and twelve Take them from my matrix and then To the columns apply a function which just takes this column as An input right and again, I'm doing the same thing Because I want to prevent Going to a factor so because if it would transform my numeric values to a factor by accident It will mess up So what I say is as numeric as character x And now what it does it takes the column out of the matrix It looks at a single column of for example the first one it converts all of the Values in this column From what they are be it factor be a date be it whatever type logical It first goes to a character and then it goes to a numeric And this is just to prevent yourself from falling into errors Where you directly call as numeric on a factor variable So always when you want to go through to numeric make sure you go via character just to make sure that Factors do not mess up the thing So very common idiom apply to part of the matrix to the columns a function of x And then as numeric as character x to take x go via character and then make it a numeric value Sometimes you want to match the input parameters to a list of allowed parameters So when you are writing your own function write It might be that you have a function which is called example It takes something called x as input be it a matrix be it a list or a vector or whatever But it also has a method, right? So for example You have developed a new algorithm and this algorithm can use three different methods For example, it can use principal components. It can use Correlation or it can use covariance, right and The user specifies which one of these three it wants Of course the user because you are giving the user the function in a package or something like that The user of course can fill out fill in anything. He doesn't have to fill in your exact Thing right it could say well I support Pca But the user says use pta right they make a typo So to prevent this and to to notify the user that he can only choose from a very limited amount of methods You can say something like this where you say well, I define a new variable called supported Which are all of the different methodologies that are supported in my case the method parameter can be either a b or c capitalized not anything else Then what I do is I do a p match So I match the method that the user input it to the function to the supported functions And now if I if this variable is not an a Then I have a valid method So then the user chose one of the methods which are supported If it is an a then you can just throw a stop error and say that the method that the user has chosen is not supported Because he didn't fill in a b or c. He probably filled in d or made some typo But this is very useful when you are writing code that you want other people to use And pay you just a very limited of think or limited set of things that the user can use Then you can then you can use the p match function to partially match The method that the user selected with a list of supported methods And hey if if an a is returned then you know that the user selected something which is not not in the list If the user selected something which is in the list then method will be the thing that the user selected Very useful for writing functions when you ever start writing functions for your own packages and Publishing your code so that other people can use them another very common idiom is When you write a function and your function returns something then the return value of a function is just Scrolled across the screen right because the same thing when I type the name of a variable It will just start rolling the thing across the screen Often a lot of functions. They have a massive return right in in this case What I'm doing is I'm just making a little example function It takes a number as input and the only thing that this does it that it repeats this thing what the user input it Like a million of times So if I would just call example one and I would not have put invisible around it then this would have Printed a million ones so it would just fill up the whole our window with one one one one one one and that's just really really annoying So if you write functions for other people Use the invisible keyword What happens is is when you type example one it will not start rolling a million ones across the screen It will just kind of eat the output. It will still generate the output You can still put the output in a variable like this And when you type the name of the variable You still see a million ones But at least when you call the function and you forget to put the result in a variable It will not start scrolling everything across the screen Which is really really annoying And using invisible prevents this massive amount of output spam from a function Just because I forgot to store the result in a variable. All right, I wanted to You Have a little bit of a different kind of common idiom, which is something that you will use a lot And I want to show you how you can do our scripts from the command line So we already use the command line when we build our own package Yes, so you then do our cmd check name of your package In the in the command line But you can use our via the command line and using our via the command line has certain massive advantages One of the advantages is that you can then run your scripts on an external server or on an external cluster Using things like secure shell So you you're not limited to only using your own computer Hey, you can write a script you can then copy the script to A remote server or to a remote cluster and then copy the data there as well And then you can run your script there directly via the command line And this helps you to Use external hardware In case that you don't have the hardware that you need at home If I do sequencing analysis, then I have to use our our server because the laptop that I'm using is not going to be good enough So the thing what you do is you make your whole analysis in a script So a single text document which starts off by setting the working directory then loading up the input files But of course because it is a script It might be that the input files or that you that you want to run it like five times Because I have five different input files or I have three different input files or a hundred Right, so I write the script and then I then I just assume that the name of the input file is going to be in a variable So that's the way that I write it. So I just define an empty variable Or at the beginning of my script saying this is the name of the file that I need to load in and do the analysis on so To be able to then fill in this Kind of magical variable which file do I need to do the analysis on you can then use command line parameters So we'll see an example about this soon. The only thing that I want to kind of Make sure that when you start writing scripts So an analysis script, which you are going to run via the command line You need to always end with a quit no at the end Because otherwise it will run through all the commands that you did it will reach the end of the script and it will just stay there Because it has no it won't quit R automatically So you as a user have to tell R to quit at the end of the script So hey, you write your whole script. So you load in your file. You do your analysis You write your output and then the last line of the script ends in a quit statement So using the q function to quit and then this function needs to know if it needs to save the workspace So we never save the workspace. So we just say quit and then no And this is very important because otherwise the script will just run It will write your output file and then it will just hang there So it will just not continue because it didn't get any order to quit down So it's still waiting for input, but no input will ever come And of course if you are on a server Where other people are also working It's not really nice to leave programs running for weeks on end before killing them So how do you do this? So Create a new file and I always put kind of the following code inside So the first code the first line of code Uses the command arcs function. So command arcs are the command line arguments that were provided to the script And here I first check if I get at least one command line argument back Because if I don't get any arguments, then I do not know what for example The name is of the file that I have to start analyzing, right? So I always want at least one argument to my script And if this is not the case, I have to quit right always quit the script As soon as possible because otherwise r will just continue there and it will just Do a stop error, but it will never quit the r session. So make sure that you quit your script when there is an error So I can use command arcs And then I get a new variable called command line arguments and I assign it to it If the length of this thing is more than one, then I'm just going to select the first one I'm going to say as character and then this is my arc one So this is my first argument that was given to the script And generally the first argument that you want to give to the script is the name of the file that you're going to analyze Right, so then I would have here normally a retable arc one Or read comma separated file arc one and then call that my data And then the rest of the script would just be analyzing and data Calculating some statistics and then writing it out Here I'm just going to write the argument to the screen And then I'm going to quit the script because that's what I should do. I cannot leave r running Just because I don't want to quit it at this point So then I open up the terminal right and I go for example to where I have stored my script And then the thing that I'm doing is just saying r script My r my script dot r. So this is the r file that I just created and then here I give the parameter So in this case, I just say something and but this would normally be For example data set one dot txt And then the next time that you're going to call it you're going to call r script my script data set two dot csv Right and in this way I can have r running in parallel on the same server like 20 times and every time The same script Analyzes a slightly different file. So for example, if I think about mice Have mice of 20 chromosomes. So I might have a script which analyzes a single chromosome And I just call this script 20 times on the server every time saying r script My script that I want to execute chromosome one dot txt My script chromosome two dot txt, right? And then it will just start up the script and even if the script runs for like an hour or two It will just do all 20 of them in parallel. So instead of waiting 20 times Two hours. I now wait only two hours in total because it does 20 chromosomes next to each other automatically So move where your script is stored using cd So change directory and then you can execute your script by just typing r script The name of the script that you created and then the name of the thing that you want to analyze And generally the name of the thing that you want to analyze is something like my data one dot txt or chromosome one dot vcf or just the input file So that that's a very common structure on how to use the command line to run our multiple times next to each other So that instead of having to do it in a for loop Yeah, you can do chromosome one chromosome two and chromosome three next to each other in parallel And be done three times as fast as if you would go in a for loop one after another Of course when we are dealing with building up these command line scripts We also want to execute external programs or a lot of the time we need to execute external programs For example, a whole bunch of next generation sequencing tools Are not available for r. They are available as command line tools The same thing holds when you think about gwas programs A lot of gwas programs are only available as standalone executables. For example, plink Or other tools You have a massive amount of tools which are not available directly in r but available via the command line And so for example next generation sequencing data Generally, there's a lot of different tools involved. So you need an aligner You need like things to check data You need to convert and so there's a whole bunch of steps that need to go in order And every time you need to use an external program to do that The same thing when you're analyzing image files have for example If you have microarray data and had the microarray data, you didn't get the cell files But you got the original kind of tiff files And then you have to go through all of the different photos of the different microarrays and for each of these extract the data from The microarray and put it in a csv file And there's a lot of command line tools which are not directly available in r So something like blast or a clusterl omega or the variant effect predictor And then there's literally hundreds and hundreds of tools which are available which you can only run via the command line So how do you do that in r? Well, this is something that I always use So this is my execute function and the execute function is nothing more than a wrapper around the function called system. So the main Workhorse here is the system function But I always want to have additional safeguards in a way because the system doesn't automatically quit when there's an error And I do want to quit because often when I'm running a pipeline I call different tools But if any of these tools fail, I also want to stop doing my pipeline right because if The aligner fails and doesn't align the sequencing reads to the genome. It makes no sense to continue with the next step So I have my execute function. It gets a parameter called x which is the the A character string that is going to execute It has a function a parameter called intern. So this means Does r need to load the data or the output of the program back into r? And generally that's not the case. So the default value is false And I have an additional parameter called quit on error And that is true because I do want to quit when the error occurs because of the fact that otherwise r will just continuously hang there Or worse, it will continue with the next step without having done the current step or with an error on the current step So what do I do? Well, I first do a couple of prints So I print out the command that I'm going to execute Then I'm using the system function to execute this command Specifying if I want to get back the output from the program or not. So generally I don't want to output from the program back So if I'm not intern I print the result Right because I want to know if the program finishes. Yes or no So if this is a zero the program finished successfully if this is not a zero an error has occurred So if I'm not intern and I and a zero had occurred and it's not a zero, right? So somewhere an error occurred and I have a quit on error. Then I just quit Otherwise I just return the result invisibly Just to prevent spamming So for example, I can now use it to do a dear command Right. So normally if I would go to the command line and I will just type in dear It would list all of the files in the current working directory. So I can do the same thing now from r. So I can say execute dear This will not show me anything because of the invisible However, when I execute dear and say Don't do it internally. So so give me back the thing that That it tells me and then I can now store it in a variable But often I use it like this. So I can often I just call I use the execute function To for example go through a list of files and then execute the r script my script with an additional parameter so had this will 10 times call An external program the external program that I'm calling in this case is r. So I'm having an r script calling r externally specifying that this external r script needs to run my script r And then the input parameter is x which in this case is one the second time And so this will in very quick succession just fire up 10 r instances And every instance will be able to analyze their own part of the data So this is this is something that I use very Very very much. I use this a lot to execute external programs like blast or the vp Or other tools in biology where there's no direct r equivalent of the tool So you have to use the command line to execute other tools that do support the function that you want All right, so that was it for today. So today we talked a little bit about common idioms like how do I use l apply? grep g sub executing external commands We talked about logistic regression and about glms, which is just the same as doing an lm But where the response variable is different. So for example a binary outcome saying healthy or sick Or affected unaffected And besides that, of course the glm model allows you to use a lot of different A lot of different distributions. Hey, so it doesn't have to be just binomial It can also be like a Poisson distribution or quasi Poisson. So hey our supports I think around 12 different distributions Some of these distributions you can even tweak. Hey, you can give additional parameters saying well, it's a gaussian distribution But it's a little bit plotty curty or it's a little bit lepto curty So it's a little bit stretched out or it's a little bit squeezed And that will give you more power to detect effects And of course when you when you're predicting a non-normal Not continuous variable head then of course you have to specify the correct link function So the correct family for r to know how to analyze your day All right, so that's it for the new stuff for today and actually for the whole Lecture I think we will have fishy data next week, but there won't be any Really new stuff because I'm just going to use all of the things that we've been talking about for the last 11 lectures to analyze the fishy data although I am using 3d matrices in the fishy data. So that might be interesting for next Week for you guys to show how you can use More than two-dimension like normally when you think about a matrix head and you think about having a two-dimensional structure Which having rows and columns But in r you can also make three-dimensional or four-dimensional matrices So a three-dimensional matrix would be a cube where you have like a depth a width and a A third dimension, but you can also make four-dimensional cubes And that helps a lot when you want to kind of get a Handle on data, which has many different dimensions And hey, you don't want to write For every dimension the same function But that's about it. So that was more or less the course I will do a short break and after the break I will go through all of the lectures one by one And highlight what I think is important so that you guys can Study more Targeted for the exam All right, so then see you guys in In seven eight minutes, so we'll continue at four p.m. 405 p.m. And There's no question so far then We'll go to the second break which should be goats, I think Again, I think we already did go through goats recently, but I just like the animated gives All right, so then see you guys in In Like 10 minutes and enjoy the animated gifts