├── README.md ├── 7.Packages.md ├── 3.IfStatements.md ├── 4.ForLoops.md ├── 1.NumbersStrings_Variable.md ├── 5.WhileLoops.md ├── 8.Functions.md ├── 2.Comparisons_Logic.md ├── 6.Lists.md └── 9.RandomExpectedGoals.md /README.md: -------------------------------------------------------------------------------- 1 | # R Basics with FC rSTATS 2 | 3 | FC rSTATS aim to make the basics of learning R accessible to those that wish to learn, but may not have the advantage of access to paid resources or a background in maths of programming. 4 | 5 | We recommend that you get RStudio installed with the instructions [here](https://courses.edx.org/courses/UTAustinX/UT.7.01x/3T2014/56c5437b88fa43cf828bff5371c6a924/), then follow along with our basics series listed below. The examples within certainly aren’t exhaustive, but they will give you an accessible introduction into the basic concepts with easy-to-follow examples based (sometimes tenuously!) on topics around football. 6 | 7 | FC rSTATS Crash Course: 8 | 9 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 10 | 11 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 12 | 13 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 14 | 15 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 16 | 17 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 18 | 19 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 20 | 21 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 22 | 23 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 24 | 25 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 26 | 27 | Once you have a grasp of the concepts above, you should aim to move on to our introduction to data analysis in R. Here, you’ll learn about cleaning and analysing data in R, as well as visualisation of your insights. 28 | 29 | If you have any questions, recommendations or requests, please get in touch! 30 | 31 | This is a R conversion of a tutorial series by [FC Python](https://fcpython.com/python-basics-fcpython). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 32 | 33 | -------------------------------------------------------------------------------- /7.Packages.md: -------------------------------------------------------------------------------- 1 | Packages in R 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/python-modules). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | R is a versatile piece of kit straight out of the box. By itself it can do just about anything, from simple calculations, to automating a Twitter account, through to being a robot’s ‘brain’. However, we can make most jobs that we will do in R a lot easier by using packages – sort of like R add-on kits. These packages create groups of functions that make tasks quicker to write and perform. Without them, we’d have to write horribly lengthy code once we got beyond simple tasks. 7 | 8 | To use a packages, you must first install it then make sure the package is loaded into any code that will use it. This article will take you through both steps: 9 | 10 | Installing Packages 11 | ------------------- 12 | 13 | It is very easy to install packages within R with the function install.packages("name\_of\_package"). 14 | 15 | example of installing the dpylr packge 16 | ====================================== 17 | 18 | install.packages("dplyr") 19 | 20 | Loading Packages 21 | ---------------- 22 | 23 | There are two ways of loading packages via the require() and the library() functions. The only difference is that if the package is not installed the require() function will output a warning whereas library will throw an error. I prefer require() but you can chose your own tools. 24 | 25 | example of loading the dpylr packge 26 | =================================== 27 | 28 | require(dplyr) 29 | 30 | Summary 31 | ------- 32 | 33 | Harvard’s Introduction to Computer Science course opens with the discussion that we are ‘standing on the shoulders of giants’, highlighting the work of programmers before us that have built languages, modules and tools that allow us to be more productive.The R community is a perfect example of this, with thousands of packages available to us that make complex tasks a bit more manageable. 34 | 35 | See some of these packages in action across data analysis, visualisation and web scraping. 36 | 37 | 38 | ## The Rest of the Series 39 | 40 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 41 | 42 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 43 | 44 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 45 | 46 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 47 | 48 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 49 | 50 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 51 | 52 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 53 | 54 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 55 | 56 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 57 | 58 | -------------------------------------------------------------------------------- /3.IfStatements.md: -------------------------------------------------------------------------------- 1 | If Statements 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/if-statements). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | Having R tell us if something is true or not is fundamental to anything that we want to do in programming. Based on something being true or false, we can tell our code to do something. By using if statements, R is able to evaluate information and act accordingly. 7 | 8 | “If this wall only has three players, I can get it into the top corner. I’ll shoot.” “If they are playing 3 defenders, I will need to select quick wingers to exploit space.” 9 | 10 | Let’s take a look at an example with some numbers. 11 | 12 | ``` r 13 | if (11 > 10){ 14 | print("Done!") 15 | } 16 | ``` 17 | 18 | ## [1] "Done!" 19 | 20 | Simple enough. 21 | 22 | If the statement "11 is greater than 10" is true, print done. But what if we give something as false? 23 | 24 | ``` r 25 | if (9 > 10){ 26 | print("Done!") 27 | } 28 | ``` 29 | 30 | Nothing happens! But we can tell the statement to do something in the case of something false: 31 | 32 | ``` r 33 | if (9 > 10){ 34 | print("Done!") 35 | }else{ 36 | print("That was false!") 37 | } 38 | ``` 39 | 40 | ## [1] "That was false!" 41 | 42 | The ‘else’ statement adds the instructions on what to do if it is false. Please pay close attention to how we structure this and where the '{' and the '}' are placed. 43 | 44 | In 2100, Oldcastle United take the brave step of hiring a robot head coach. Throughout the game, Bobby Roboson decides to tell his players to attack more or less depending on the score. eGaffer may use the following code: 45 | 46 | ``` r 47 | OldcastleScore = 0 48 | OpponentScore = 0 49 | 50 | if (OldcastleScore < OpponentScore){ 51 | print("ATTACK ATTACK ATTACK!") 52 | }else{ 53 | print("10 men behind the ball!") 54 | } 55 | ``` 56 | 57 | ## [1] "10 men behind the ball!" 58 | 59 | So above, if the opponent are ahead, Oldcastle attack. Otherwise, they play ultra-defensively. 60 | 61 | We don’t seem to have taken account for a draw. Let’s upgrade iCoach with an ‘else if’ statement. 62 | 63 | ``` r 64 | OldcastleScore = 0 65 | OpponentScore = 0 66 | 67 | if (OldcastleScore < OpponentScore){ 68 | print("ATTACK ATTACK ATTACK!") 69 | } else if (OldcastleScore == OpponentScore){ 70 | print("Stay solid, but exploit any opportunity!") 71 | }else{ 72 | print("10 men behind the ball!") 73 | } 74 | ``` 75 | 76 | ## [1] "Stay solid, but exploit any opportunity!" 77 | 78 | Awesome, our coach has increased his decision making by 50%! It now checks to see if we are losing, if we are drawing or if anything else is happening (which can only be winning). If you change the scores in the example, it will react accordingly. Pretty cool! 79 | 80 | Summary 81 | ------- 82 | 83 | If statements are fundamental to programming – they give machines the ability to react based on information that it receives. 84 | 85 | Between ‘if’, ‘else if’ and ‘else’, we gave a coach the ability to assess the scoreline and act accordingly. Great job! 86 | 87 | 88 | ## The Rest of the Series 89 | 90 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 91 | 92 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 93 | 94 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 95 | 96 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 97 | 98 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 99 | 100 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 101 | 102 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 103 | 104 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 105 | 106 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 107 | 108 | -------------------------------------------------------------------------------- /4.ForLoops.md: -------------------------------------------------------------------------------- 1 | For Loops 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/for-loops). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | Everything that we have seen so far has involved us giving a program a single instruction and asking it to run. This is not particularly efficient if we want to do the same thing several times over. We would much rather find a way to automate this and run the task multiple times for us, for loops are the perfect way to get started here. 7 | 8 | Lists 9 | ----- 10 | 11 | We cover lists and other group concepts elsewhere, but a list is simply a way to group lots of things into one variable. A list has lots of functions that make it easy to work with – please see its own page for more on this. This list is a 3-a-side team selected to play in a TV commercial. 12 | 13 | ``` r 14 | TeamA = c("Nasta","Overvenus","Ranalda") 15 | ``` 16 | 17 | The TV commercial wants to announce these players to the crowd. We can do this individually for each: 18 | 19 | ``` r 20 | print(paste0("Welcome to the cage, ", TeamA[1])) 21 | ``` 22 | 23 | ## [1] "Welcome to the cage, Nasta" 24 | 25 | ``` r 26 | print(paste0("Welcome to the cage, ", TeamA[2])) 27 | ``` 28 | 29 | ## [1] "Welcome to the cage, Overvenus" 30 | 31 | ``` r 32 | print(paste0("Welcome to the cage, ", TeamA[3])) 33 | ``` 34 | 35 | ## [1] "Welcome to the cage, Ranalda" 36 | 37 | Notice how we repeated ourself three times? ‘For loops’ help us to avoid doing so. The smarter announcer is run using the following code: 38 | 39 | ``` r 40 | for (player in TeamA) { 41 | print(paste0("Welcome to the cage, ", player)) 42 | } 43 | ``` 44 | 45 | ## [1] "Welcome to the cage, Nasta" 46 | ## [1] "Welcome to the cage, Overvenus" 47 | ## [1] "Welcome to the cage, Ranalda" 48 | 49 | Our output is exactly the same, but the code looks so much better! 50 | 51 | The essential bits to our code are the words ‘for’ and ‘in’, \*\*\* 52 | 53 | Plus, we could also add a second team really really easily with a ‘nested for-loop’ – this is a for-loop inside a for-loop! 54 | 55 | ``` r 56 | #Team 2, enter! 57 | TeamB = c("Tatti","Nikita","Hanry") 58 | 59 | #A list of lists! 60 | Teams <- c(TeamA,TeamB) 61 | 62 | for (team in Teams) { 63 | for (player in team) { 64 | print(paste0("Welcome to the cage, ", player)) 65 | } 66 | } 67 | ``` 68 | 69 | ## [1] "Welcome to the cage, Nasta" 70 | ## [1] "Welcome to the cage, Overvenus" 71 | ## [1] "Welcome to the cage, Ranalda" 72 | ## [1] "Welcome to the cage, Tatti" 73 | ## [1] "Welcome to the cage, Nikita" 74 | ## [1] "Welcome to the cage, Hanry" 75 | 76 | So cool! 77 | 78 | Summary 79 | ------- 80 | 81 | If we have to write down every single thing that we want our code to do, it will be hugely inefficient and a bit of a pain to write. We can utilise for loops to automate any repetition and to try our best to avoid duplicate code. In fact, programming has a DRY mantra – “Don’t repeat yourself”. 82 | 83 | Our examples above demonstrate a nested for-loop too – a loop within a loop to push our automation even further. 84 | 85 | Give them a try yourself, and check out while loops when you’re comfortable here! 86 | 87 | 88 | ## The Rest of the Series 89 | 90 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 91 | 92 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 93 | 94 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 95 | 96 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 97 | 98 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 99 | 100 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 101 | 102 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 103 | 104 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 105 | 106 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 107 | 108 | -------------------------------------------------------------------------------- /1.NumbersStrings_Variable.md: -------------------------------------------------------------------------------- 1 | Numbers, Strings and Variables in R 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/numbers-string-variables-python). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | Football is full of numbers, names, lists, teams and a million other ‘things’ that make up our understanding of what is happening. 7 | 8 | In the same way, R has lots of different ways of classifying things that it can understand. For example, it uses numbers to count, ‘strings’ for names and even has ways to group these things – like we would need for a league. This introductory post takes a look at a couple of these data types. 9 | 10 | Numbers 11 | ------- 12 | 13 | As its simplest, R is a calculator: 14 | 15 | ``` r 16 | 1+1 17 | ``` 18 | 19 | ## [1] 2 20 | 21 | ``` r 22 | 10*2 23 | ``` 24 | 25 | ## [1] 20 26 | 27 | ``` r 28 | 20/2 29 | ``` 30 | 31 | ## [1] 10 32 | 33 | ``` r 34 | # ** = to the power of 35 | 2**3 36 | ``` 37 | 38 | ## [1] 8 39 | 40 | Variables 41 | --------- 42 | 43 | While a calculator is incredibly useful, we can give these numbers a name and a placeholder so that they are a bit more tangible and applicable to a problem. For example, if I want to keep track of our top scorer’s shots and goals: 44 | 45 | ``` r 46 | Ronney_Goals <- 15 47 | Ronney_Shots <- 63 48 | ``` 49 | 50 | I could now calculate Ronney’s conversion rate! Dividing goals by shots, I can see how many shots it takes him to score. 51 | 52 | ``` r 53 | Ronney_Conversion = Ronney_Goals/Ronney_Shots 54 | Ronney_Conversion 55 | ``` 56 | 57 | ## [1] 0.2380952 58 | 59 | Strings 60 | ------- 61 | 62 | Now that R has some interesting information on Ronney, it wants to share it with the world. As we can see above, sharing a number by itself doesn’t tell us a great deal. However, a string of text can give us a bit of context. 63 | 64 | Surround a piece of text in quotation marks (be consistent with single or double quotes) to create a string: 65 | 66 | ``` r 67 | "Ronney is truly a great player, his conversion rate speaks for itself." 68 | ``` 69 | 70 | ## [1] "Ronney is truly a great player, his conversion rate speaks for itself." 71 | 72 | …and let’s use the print() and paste0() commands to add the evidence to our commentator’s opinion. 73 | 74 | ``` r 75 | print(paste0("His conversion rate of ", Ronney_Conversion, " is sublime")) 76 | ``` 77 | 78 | ## [1] "His conversion rate of 0.238095238095238 is sublime" 79 | 80 | That is a bit specific, Merse, but I appreciate the information! Let’s take a look at those two commands: 81 | 82 | print() – R, please print everything that I put into the brackets. 83 | 84 | paste0() – R, combine this segments of text and numbers 85 | 86 | Summary 87 | ------- 88 | 89 | In this introductory post, we have seen that R can be used as a calculator at its very simplest. However, we have seen that we can make it a bit more useful with variables, even using a variable to help our commentator give a great bit of insight, combining it with a string. 90 | 91 | We even saw a couple of commands with print() and paste0(). 92 | 93 | Next up, take a look at how we compare and evaluate this information in R to make decisions with our code. 94 | 95 | ## The Rest of the Series 96 | 97 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 98 | 99 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 100 | 101 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 102 | 103 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 104 | 105 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 106 | 107 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 108 | 109 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 110 | 111 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 112 | 113 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 114 | 115 | -------------------------------------------------------------------------------- /5.WhileLoops.md: -------------------------------------------------------------------------------- 1 | While Loops in R 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/while-loops). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | As seen with their ‘for’ counterpart, loops are a really useful tool that allow us to repeat instructions without repeating our code. It keeps programs light and easier to understand. For loops ran for a set amount of times – a number that we explicitly provide. Where while loops differ is that they will run until told not to. Take the example below: 7 | 8 | ``` r 9 | watchMinutes <- 0 10 | 11 | while (watchMinutes < 45){ 12 | watchMinutes <- watchMinutes + 1 13 | } 14 | print(paste0(watchMinutes, " played, it is half-time!")) 15 | ``` 16 | 17 | ## [1] "45 played, it is half-time!" 18 | 19 | Above, the referee starts their watch at 0 minutes. A while loop then begins, increasing the watchMinutes counter by 1 each time it runs. 20 | 21 | It runs until the statement after ‘while’ becomes false (in this case, until minutes passes 45). It then stops and continues with the rest of the code – telling us that it is half time. 22 | 23 | The structure is pretty simple, but we have to be very careful when using while loops. If the while statement never turns to ‘False’, we will create an infinite loop and break the program. Use carefully, or just use for loops where you can! 24 | 25 | Let’s get another, more complex example, for a team that wants to see how many passes it might make, depending on its pass success rate. 26 | 27 | It wants to know how many passes it can expect to make in a row, if they know that their pass success rate is 66%. 28 | 29 | ``` r 30 | keepPossession <- TRUE 31 | passSkill <- 66 32 | passesComplete <- 0 33 | 34 | while (keepPossession == TRUE){ 35 | 36 | if (sample(1:100,1) > passSkill){ 37 | keepPossession <- FALSE 38 | }else{ 39 | passesComplete <- passesComplete + 1 40 | } 41 | 42 | } 43 | print(passesComplete) 44 | ``` 45 | 46 | ## [1] 1 47 | 48 | So if your team has a 66% pass completion rate, you really can’t expect much flowing football! 49 | 50 | Let’s break this down. 51 | 52 | keepPossession: this tells R is it ‘True’ or ‘False’ that we keep the ball? passSkill: The % chance that we will keep the ball after a pass. Feel free to change this and see what numbers come up (but avoid 100 or more!)! passesComplete: This is simply our counter of how many passes. 53 | 54 | We then run our while loop. This will run infinitely until we lose possession (keepPossession equals False). 55 | 56 | In this loop, we add one pass to our counter, then run a random number generator with the sample() function. If this random number is greater than our skill level, we lose the ball and set keepPossession to False. 57 | 58 | Once the loop is over, we receive our passesComplete count. If we do this lots of times, we’ll get a good average that we can expect to make each time, with some distribution above and below this number. Pretty cool – maybe find the % for your team and see what you can expect! 59 | 60 | Summary 61 | ------- 62 | 63 | While loops give us another way to repeat our code, similar to the for loop. The structure is just as simple, but we need to be careful not to send our program into an infinite loop and completely break it! 64 | 65 | We used these loops to act as a ref’s watch and to estimate how many passes a team might string together on any given opportunity. You’re now adding numbers to your scouting report & have something to train your team against too! 66 | 67 | Next up, read more about the random number generation in general! 68 | 69 | 70 | ## The Rest of the Series 71 | 72 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 73 | 74 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 75 | 76 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 77 | 78 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 79 | 80 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 81 | 82 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 83 | 84 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 85 | 86 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 87 | 88 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 89 | 90 | 91 | -------------------------------------------------------------------------------- /8.Functions.md: -------------------------------------------------------------------------------- 1 | Creating Functions 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/creating-functions). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | In previous posts, we have seen a couple a couple of examples of functions – print() being just one of them. 7 | 8 | As you know, functions are ways for us to give an instruction to a program. Out of the box, R has lots of them – and packages add even more. But there are many instances when we might want to create our own. They can save us repeating code, they can give us code that we share with other people or future programs that we will write. 9 | 10 | Creating them is simple: 11 | 12 | ``` r 13 | doubleMe <- function(number){ 14 | return(number * 2) 15 | } 16 | 17 | doubleMe(2) 18 | ``` 19 | 20 | ## [1] 4 21 | 22 | In just two lines, we have introduced a new function called ‘doubleMe’! Let’s break this down bit by bit: 23 | 24 | The first line uses the function definer function and tell R to save it as a name, in this case doubleMe. We then tell it what arguments it is going to need – any we gave this function one argument, called ‘number’. ‘Number’ is just a name, we could have called this anything, but it helps us to give a comprehensible name. Why make life more difficult?! 25 | 26 | After the arguments list in brackets, add a {. 27 | 28 | On the next line we give instructions as to what to do with these arguments. In this example, we return the ‘number’, multiplied by 2! 29 | 30 | Let’s create a function that creates a Tweet for our live text commentary: 31 | 32 | ``` r 33 | newTweet <- function(player, action, success){ 34 | 35 | tweet <- "" 36 | if(success){ 37 | 38 | if(action == "pass"){ 39 | tweet <- paste0(player, " plays a ", action, ". The team keep possession") 40 | }else{ 41 | tweet <- paste0(player, " plays a ", action, ". GOOOOOAAAAAAALLLLLL") 42 | } 43 | 44 | }else{ 45 | 46 | if(action == "pass"){ 47 | tweet <- paste0(player, " plays a ", action, ". The pass is unsuccessful") 48 | }else{ 49 | tweet <- paste0(player, " plays a ", action, ". No goal this time!") 50 | } 51 | 52 | } 53 | return(tweet) 54 | } 55 | 56 | newTweet("Pearlo", "shot", TRUE) 57 | ``` 58 | 59 | ## [1] "Pearlo plays a shot. GOOOOOAAAAAAALLLLLL" 60 | 61 | We have just created a program that creates tweets for us, based on three arguments – player, action and success. 62 | 63 | It takes the first two arguments and creates the first sentence in the tweet. It then takes the True or False value in success to decide what to add to the end of the tweet with some nested if statements. Hopefully these are simple enough to follow along with! 64 | 65 | The function finally returns the new tweet, which we can manually add to our feed. Did you know there is a Twitter package for Python that will allow you to post directly to Twitter?! A lesson for another day. 66 | 67 | Summary 68 | ------- 69 | 70 | Here, we have seen how to define functions with the following structure: 71 | 72 | functionName <- function(Arguments){ ---do something with arguments--- } 73 | 74 | This allows us to write reusable code that will make our programs smarter, tidier and sharable! They incorporate if statements, for loops and everything else that you have learned and will learn in R. 75 | 76 | In our example, we created a small function that creates tweets for us for a live text commentary, that save us typing out the same things repeatedly. It wasn’t particularly smart, but we’ll get there! 77 | 78 | 79 | ## The Rest of the Series 80 | 81 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 82 | 83 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 84 | 85 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 86 | 87 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 88 | 89 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 90 | 91 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 92 | 93 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 94 | 95 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 96 | 97 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 98 | 99 | 100 | -------------------------------------------------------------------------------- /2.Comparisons_Logic.md: -------------------------------------------------------------------------------- 1 | Comparisons and Logic 2 | ================ 3 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/comparisons-and-logic). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 4 | 5 | Every day, we make thousands of tiny judgements that lead to bigger actions. Based on the information available, we will make what we judge to be the right decision. The programs that you will write will be exactly the same – we will feed it information, it will evaluate it and proceed accordingly. 6 | 7 | On the pitch, do I take a shot or lay it off for a better chance elsewhere? In the manager’s office, does he sign a new goalkeeper, or show faith in the academy? Decisions are made on the information available – let’s take a look at how this is done in R. 8 | 9 | Comparison Operators 10 | -------------------- 11 | 12 | You may be familiar with comparison operators from other programming languages or even in Excel. These are used to ask the relationship between two values. Is one bigger than another? Are they the same? 13 | 14 | They will return with either ‘True’ or ‘False’. Eventually, we will write programs that make decisions based on these evaluations. 15 | 16 | Let’s use some simple examples with numbers: 17 | 18 | ``` r 19 | # Is four greater than three? 20 | 4 > 3 21 | ``` 22 | 23 | ## [1] TRUE 24 | 25 | ``` r 26 | # Is four less than three? 27 | 4 < 3 28 | ``` 29 | 30 | ## [1] FALSE 31 | 32 | ``` r 33 | # Is 20 less than or equal to 21? 34 | 20 <= 21 35 | ``` 36 | 37 | ## [1] TRUE 38 | 39 | ``` r 40 | # Does 44 equal 44? We use 2 equals signs here! 41 | 44 == 44 42 | ``` 43 | 44 | ## [1] TRUE 45 | 46 | Remember our variables section? Let’s assign a skill ranking to some players and evaluate them. 47 | 48 | ``` r 49 | # Our skill ranking system assigns two players a ranking, Who is better? 50 | 51 | Garrerd = 99 52 | Landard = 98 53 | 54 | Garrerd > Landard 55 | ``` 56 | 57 | ## [1] TRUE 58 | 59 | Logic Operators 60 | --------------- 61 | 62 | Logic operators allow us to use multiple comparisons together. This is really useful as we can quickly ask more complex questions from our programs. 63 | 64 | Let’s take the example above. Why don’t we check if we can afford to purchase the better player, assuming they both cost the same? 65 | 66 | ``` r 67 | # Garrerd = 99 and Landard = 98 as in the last example 68 | # Check that Garrerd is better AND that can we afford them? 69 | 70 | Budget = 5000000 71 | PlayerCost = 4000000 72 | 73 | (Garrerd > Landard) & (Budget >= PlayerCost) 74 | ``` 75 | 76 | ## [1] TRUE 77 | 78 | Sign him up! 79 | 80 | By using the ‘&’ symbol, we test if both things are true. If just one has to be true, we can use the ‘|’ symbol instead. 81 | 82 | In this new example, our star striker gets a £1,000,000 bonus if she scores more than ten goals or makes at least 15 assists. Let’s test to see if she did it. 83 | 84 | ``` r 85 | HerderGoals = 9 86 | HerderAssists = 16 87 | 88 | (HerderGoals > 10) | (HerderAssists >= 15) 89 | ``` 90 | 91 | ## [1] TRUE 92 | 93 | Lucky Herder! 94 | 95 | Herder gets her bonus! Her teammate Merta, however, is a bit of a loose cannon. Her bonus is given if she scores more than 5 goals, or makes 5 assists AND receives fewer than 3 red cards. Let’s test this. 96 | 97 | ``` r 98 | MertaGoals = 5 99 | MertaAssists = 10 100 | MertaRedCards = 3 101 | 102 | (MertaGoals > 5) | ((MertaAssists>=5) & (MertaRedCards<3)) 103 | ``` 104 | 105 | ## [1] FALSE 106 | 107 | Looks like Merta’s temper has cost her here. While she easily made the number of assists, her red card record let her down. 108 | 109 | Pay close attention to how the brackets show Python what the clauses are in our ‘or’ and ‘and’ statements! 110 | 111 | Summary 112 | ------- 113 | 114 | In this piece, we have seen how Python assesses numbers. We can use our operators (<,>, etc.) to ask true or false questions. We can make these even more complex with and/or operators too. 115 | 116 | In our basic examples, we used it to quickly check player ratings and affordability. We also used it to check if our players earned their bonuses. 117 | 118 | For next steps, we need to tell R to do something based on these actions. We can do this with if statements in the next article! 119 | 120 | 121 | ## The Rest of the Series 122 | 123 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 124 | 125 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 126 | 127 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 128 | 129 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 130 | 131 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 132 | 133 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 134 | 135 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 136 | 137 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 138 | 139 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 140 | 141 | -------------------------------------------------------------------------------- /6.Lists.md: -------------------------------------------------------------------------------- 1 | Lists in R 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/lists-in-python). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | Using single numbers or data points will only get us so far. If we want to analyse data sets or do anything with more than one number, it would be very helpful to have tools that grouped numbers. Fortunately, R gives us several of these which will help to solve different problems. This article looks at one of these tools – ‘Lists’. We will learn what a list is, how we can use them in functions, and methods that help us to get more use out of them. 7 | 8 | Lists are our simplest way to group numbers. They are simply a list of values – whether that is numbers, text, variables or even another list. Let’s put our ‘goals for’ and ‘goals against’ from our team’s first 9 games into a list: 9 | 10 | ``` r 11 | GF = c(0,0,3,2,1,5,3,1,2) 12 | GA = c(2,0,2,2,3,2,3,2,4) 13 | 14 | print(GF) 15 | ``` 16 | 17 | ## [1] 0 0 3 2 1 5 3 1 2 18 | 19 | ``` r 20 | print(GA) 21 | ``` 22 | 23 | ## [1] 2 0 2 2 3 2 3 2 4 24 | 25 | Accessing numbers in lists is easy. Let’s take the numbers from our first game. 26 | 27 | We do this by calling the list name, and adding square brackets with a number on the end. We will get the value held in the positon of the number. 28 | 29 | This order starts at 1 – so for the first game, we will put 1. The second, we put 2, the third, we put 3 and so on. 30 | 31 | ``` r 32 | print(GF[1]) 33 | ``` 34 | 35 | ## [1] 0 36 | 37 | ``` r 38 | print(GA[1]) 39 | ``` 40 | 41 | ## [1] 2 42 | 43 | Looks like we lost 2-0. Let’s make sure: 44 | 45 | ``` r 46 | GF[1] - GA[1] 47 | ``` 48 | 49 | ## [1] -2 50 | 51 | Yup, a loss and -2 goal difference. 52 | 53 | Let’s iterate through this list to get our goal difference and also our points for the season so far. 54 | 55 | ``` r 56 | #Define variables for points and goal difference 57 | #Set goals for and against 58 | 59 | P <- 0 60 | GD <- 0 61 | GF <- c(0,0,3,2,1,5,3,1,2) 62 | GA <- c(2,0,2,2,3,2,3,2,4) 63 | 64 | #We have 9 games, so we iterate with a range of 9 in a for loop 65 | for (i in seq(1:9)){ 66 | #If we score more, give us 3 points and add the goal difference 67 | if(GF[i] > GA[i]){ 68 | P <- P +3 69 | GD <- GD + (GF[i] - GA[i]) 70 | }else if(GF[i] == GA[i]){ 71 | P <- P + 1 72 | }else{ 73 | GD <- GD + (GF[i] - GA[i]) 74 | } 75 | } 76 | print(P) 77 | ``` 78 | 79 | ## [1] 9 80 | 81 | ``` r 82 | print(GD) 83 | ``` 84 | 85 | ## [1] -3 86 | 87 | Seqence seq() 88 | ------------- 89 | 90 | In those 9 games, we received 9 points and had a -3 GD. We can change the lists to be any length, and change the number in the ‘seqence’ to calculate this over any number of games! 91 | 92 | ‘Seqence’ is a function that generates a series of numbers between two points. By default, it starts at 1 and goes to whatever number we give it. Let’s take a look at some examples: 93 | 94 | ``` r 95 | #One argument in range() 96 | #Give me the list of 10 numbers, starting at 0 97 | seq(0,9,1) 98 | ``` 99 | 100 | ## [1] 0 1 2 3 4 5 6 7 8 9 101 | 102 | ``` r 103 | #Two arguments in range() 104 | #Give me all numbers between these two 105 | seq(5,10,1) 106 | ``` 107 | 108 | ## [1] 5 6 7 8 9 10 109 | 110 | ``` r 111 | #Three arguments in range() 112 | #Give me all numbers between the first two, in steps of the third number 113 | seq(0,10,2) 114 | ``` 115 | 116 | ## [1] 0 2 4 6 8 10 117 | 118 | We then used this range as our counter for how many times we used the for loop. Keep this in mind for future loops! 119 | 120 | Selecting a number from a list 121 | ------------------------------ 122 | 123 | Selecting a number from a list is easy. Just pop the index (the location of the number) in square brackets after the list name. 124 | 125 | Select multiple with a colon between two numbers – including the first of them, but not the last. 126 | 127 | ``` r 128 | Players <- c("Didek","Bascin","Smacer","Boras","Finnon") 129 | 130 | #Select the 4th player - remember that the count starts at 0! 131 | print(Players[4]) 132 | ``` 133 | 134 | ## [1] "Boras" 135 | 136 | ``` r 137 | #Select the middle 3 players (Bascin, Smacer and Boras) 138 | print(Players[2:4]) 139 | ``` 140 | 141 | ## [1] "Bascin" "Smacer" "Boras" 142 | 143 | List Methods 144 | ------------ 145 | 146 | A method is a function that belongs to a data type. It is used to manipulate or utilise this data type. 147 | 148 | For lists, this might involve adding something to the end, alphaetising our list or finding the location of something within it. 149 | 150 | A method is used by calling the name of the variable, then the method and its arguments – you can find a few below: 151 | 152 | ``` r 153 | GF <- c(0,0,3,2,1,5,3,1,2) 154 | GA <- c(2,0,2,2,3,2,3,2,4) 155 | 156 | #Let's add a new score to our goals for and goals against lists 157 | #The append() method will help us here 158 | 159 | GF <- append(GF, 3) 160 | GA <- append(GA, 1) 161 | 162 | #Show the scores, 3-1 should be the final column 163 | print(GF) 164 | ``` 165 | 166 | ## [1] 0 0 3 2 1 5 3 1 2 3 167 | 168 | ``` r 169 | print(GA) 170 | ``` 171 | 172 | ## [1] 2 0 2 2 3 2 3 2 4 1 173 | 174 | ``` r 175 | GF <- c(0, 0, 3, 2, 1, 5, 3, 1, 2, 3) 176 | GA <- c(2, 0, 2, 2, 3, 2, 3, 2, 4, 1) 177 | 178 | #I want to reverse the scores, to see the 5 most recent ones 179 | #Reverse() will make this light work 180 | 181 | GF <- rev(GF) 182 | GA <- rev(GA) 183 | print(GF[1:5]) 184 | ``` 185 | 186 | ## [1] 3 2 1 3 5 187 | 188 | ``` r 189 | print(GA[1:5]) 190 | ``` 191 | 192 | ## [1] 1 4 2 3 2 193 | 194 | There are plenty more methods for you to learn about on your journey learning R – I’m sure you’ll find lots more on the pages here, but a quick Google will take you to many more. 195 | 196 | Summary 197 | ------- 198 | 199 | Lists are a simple way to store lots of numbers under one variable. This is very useful for keeping records of things, or for running formulas that take more than one number. 200 | 201 | We have learned that they are created with c and brackets c(), can be navigated to find individual datapoints or ‘slices’ of then. 202 | 203 | We also learned about methods – functions that act on a particular class. For lists, we saw them easily add more data points, or reverse the order of them. 204 | 205 | There are more ways to store multiple data points – more on those later. 206 | 207 | 208 | ## The Rest of the Series 209 | 210 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 211 | 212 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 213 | 214 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 215 | 216 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 217 | 218 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 219 | 220 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 221 | 222 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 223 | 224 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 225 | 226 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 227 | 228 | 229 | -------------------------------------------------------------------------------- /9.RandomExpectedGoals.md: -------------------------------------------------------------------------------- 1 | Random in Python with Expected Goals 2 | ================ 3 | 4 | This is a R conversion of a tutorial by [FC Python](http://fcpython.com/python-basics/random-with-xg). I take no credit for the idea and have their blessing to make this conversion. All text is a direct copy unless changes were relevant. Please follow them on [twitter](www.twitter.com/FC_Python) and if you have a desire to learn Python then they are a fantastic resource! 5 | 6 | Creating random numbers is a central part of programming – whether it is for simulations, games or models, there are a multitude of uses for random numbers. R’s makes creating pseudo-random numbers incredibly simple. This article runs through the basic commands to create a random number, then looks to apply this to finding how likely you are to win based on a match’s expected goals (we’ll come on to what these are later). 7 | 8 | The easiest way to get a random number is through the ‘runif()’ operation. This will give a random number between 0 and 1. Check it out: 9 | 10 | ``` r 11 | runif(1) 12 | ``` 13 | 14 | ## [1] 0.8614516 15 | 16 | A number between 0 and 1 is very useful. Essentially, it gives us a percentage that we can use to calculate chance, or to assign to a variable for calculation. 17 | 18 | Additionally, we can use it to create a random whole number by multiplying it by the maximum possible value, then rounding with to the nearest integer using round(). The example here gives us a random number between 0 and 100: 19 | 20 | ``` r 21 | round(runif(1) * 100) 22 | ``` 23 | 24 | ## [1] 0 25 | 26 | Alternatively to the above, we could use another function sample() to create a random whole number for us. We simply pass the highest and lowest possible values (inclusive) that we will allow and state the amount of times to run the generation. Let’s simulate a 6-sided dice roll: 27 | 28 | ``` r 29 | sample(1:6, size = 1, replace = TRUE) 30 | ``` 31 | 32 | ## [1] 6 33 | 34 | Applying Random to Expected Goals 35 | --------------------------------- 36 | 37 | Great job on generating random numbers. The rest of the article applies it to expected goals, and will allow us to calculate how ‘lucky’ a team was based on the quality of their shots. 38 | 39 | Firstly, expected goals is a measurement of how many goals a team could have expected to score based on the shots that they took. Different models base this on different things, but most commonly, the location of the shot, type of build-up, foot used are used to compare the chance with similar ones historically. We can then see the percentage chance of the shot becoming a goal. 40 | 41 | Knowing the expected goals, we can generate random numbers to test how likely that score was. Let’s set up our lists of shots with their expected goal values – these are all percentages represented as decimals. 42 | 43 | ``` r 44 | HomexG = c(0.21,0.66,0.1,0.14,0.01) 45 | AwayxG = c(0.04,0.06,0.01,0.04,0.06,0.12,0.01,0.06) 46 | ``` 47 | 48 | The first shot for the home team had a 21% chance of being scored. Let’s create a random percentage to simulate if it goes in or not. If it is equal or less than 21%, we can say that it is scored in our simulation: 49 | 50 | ``` r 51 | if (runif(1) <= 0.21){ 52 | print("GOAL!") 53 | }else{ 54 | print("Missed!") 55 | } 56 | ``` 57 | 58 | ## [1] "Missed!" 59 | 60 | As happens roughly 4 out of 5 times, this time the shot was missed. Let’s run the shot 10,000 times: 61 | 62 | ``` r 63 | Goals <- 0 64 | 65 | for (i in 1:10000){ 66 | if (runif(1) <= 0.21){ 67 | Goals <- Goals + 1 68 | } 69 | } 70 | print(Goals) 71 | ``` 72 | 73 | ## [1] 2108 74 | 75 | So according to the xG score and our random test, if we take that shot 10,000 times, we can expect around 2075 goals (pretty much in line with the 0.21 score). In a nutshell, this is how we simulate with random numbers. 76 | 77 | Going Further: Simulating a Match with Expected Goals 78 | ----------------------------------------------------- 79 | 80 | Rather than simulate with one number, let’s apply this same test to every shot by the home and away teams. Take a look through the function below and try to understand how it applies the test above to every shot in the HomexG and AwayxG lists. 81 | 82 | ``` r 83 | calculateWinner <- function(home, away){ 84 | #Our match starts at 0-0 85 | HomeGoals = 0 86 | AwayGoals = 0 87 | 88 | #We have a function within our function 89 | #This one runs the 'runif(1)' test above for a list 90 | testShots <- function(shots){ 91 | 92 | #Start goal count at 0 93 | Goals = 0 94 | 95 | #For each shot, if it goes in, add a goal 96 | for (shot in shots){ 97 | if (runif(1)<=shot){ 98 | Goals <- Goals + 1 99 | } 100 | } 101 | 102 | #Finally, return the number of goals 103 | return(Goals) 104 | 105 | } 106 | 107 | #Run the above formula for home and away lists 108 | HomeGoals = testShots(home) 109 | AwayGoals = testShots(away) 110 | 111 | #Return the score 112 | if(HomeGoals > AwayGoals){ 113 | print(paste0("Home Wins! ",HomeGoals, " - ",AwayGoals)) 114 | } else if(AwayGoals > HomeGoals){ 115 | print(paste0("Away Wins! ",HomeGoals, " - ",AwayGoals)) 116 | }else{ 117 | print(paste0("Share of the points! ",HomeGoals, " - ",AwayGoals)) 118 | } 119 | 120 | } 121 | 122 | calculateWinner(HomexG, AwayxG) 123 | ``` 124 | 125 | ## [1] "Away Wins! 1 - 2" 126 | 127 | We are now simulating a whole game based on expected goals, pretty cool! 128 | 129 | However, we are only simulating once. In order to get a proper estimate as to how likely it is that one team wins, we need to do this lots of times. 130 | 131 | Let’s change our last function to simply return the result, not a user-friendly print out. We can then use this function over and over to calculate an accurate percentage chance of winning for each team. 132 | 133 | ``` r 134 | calculateWinner <- function(home, away){ 135 | #Our match starts at 0-0 136 | HomeGoals = 0 137 | AwayGoals = 0 138 | 139 | #We have a function within our function 140 | #This one runs the 'runif(1)' test above for a list 141 | testShots <- function(shots){ 142 | 143 | #Start goal count at 0 144 | Goals = 0 145 | 146 | #For each shot, if it goes in, add a goal 147 | for (shot in shots){ 148 | if (runif(1)<=shot){ 149 | Goals <- Goals + 1 150 | } 151 | } 152 | 153 | #Finally, return the number of goals 154 | return(Goals) 155 | 156 | } 157 | 158 | #Run the above formula for home and away lists 159 | HomeGoals = testShots(home) 160 | AwayGoals = testShots(away) 161 | 162 | #Return the score 163 | if(HomeGoals > AwayGoals){ 164 | return("home") 165 | } else if(AwayGoals > HomeGoals){ 166 | return("away") 167 | }else{ 168 | return("draw") 169 | } 170 | 171 | } 172 | 173 | #Run xG calculator 10000 times to test winner % 174 | calculateChance <- function(team1, team2){ 175 | home <- 0 176 | away <- 0 177 | draw <- 0 178 | 179 | for (i in 1:10000) { 180 | 181 | matchWinner = calculateWinner(team1,team2) 182 | 183 | if(matchWinner == "home"){ 184 | home <- home + 1 185 | }else if(matchWinner == "away"){ 186 | away <- away + 1 187 | }else{ 188 | draw <- draw + 1 189 | } 190 | } 191 | 192 | home = home/100 193 | away = away/100 194 | draw = draw/100 195 | 196 | print(paste0("Over 10000 games, home wins ", home, "%, away wins ",away,"% and there is a draw in ",draw,"% of games.")) 197 | 198 | } 199 | 200 | calculateChance(HomexG, AwayxG) 201 | ``` 202 | 203 | ## [1] "Over 10000 games, home wins 60.5%, away wins 9.78% and there is a draw in 29.72% of games." 204 | 205 | There we go! We now have a better understanding as to what result we could normally expect from these chances! 206 | 207 | Let’s try a new run of expected goals – one great chance (50%) against 10 poor chances (5%). Who wins most often here? 208 | 209 | ``` r 210 | HomexG <- c(0.5) 211 | AwayxG <- c(0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05) 212 | calculateChance(HomexG, AwayxG) 213 | ``` 214 | 215 | ## [1] "Over 10000 games, home wins 28.97%, away wins 24.72% and there is a draw in 46.31% of games." 216 | 217 | Interestingly, the big chance team has a 5% advantage over the team that shoots loads from low-chance opportunities. Makes you think! 218 | 219 | Summary 220 | ------- 221 | 222 | Creating random numbers in R is easy, whether we want a random percentage or number between 0 and 1, or we want a random whole integer. 223 | 224 | In this article, we saw how we can apply random numbers to a simulation. If anything around the function creation or for loops was confusing here, you might want to take a read up on those. 225 | 226 | 227 | ## The Rest of the Series 228 | 229 | 1. [Numbers, Strings & Variables](https://github.com/FCrSTATS/R_basics/blob/master/1.NumbersStrings_Variable.md) 230 | 231 | 2. [Comparisons & Logic](https://github.com/FCrSTATS/R_basics/blob/master/2.Comparisons_Logic.md) 232 | 233 | 3. [If Statements](https://github.com/FCrSTATS/R_basics/blob/master/3.IfStatements.md) 234 | 235 | 4. [For Loops](https://github.com/FCrSTATS/R_basics/blob/master/4.ForLoops.md) 236 | 237 | 5. [While Loops](https://github.com/FCrSTATS/R_basics/blob/master/5.WhileLoops.md) 238 | 239 | 6. [Lists](https://github.com/FCrSTATS/R_basics/blob/master/6.Lists.md) 240 | 241 | 7. [Packages](https://github.com/FCrSTATS/R_basics/blob/master/7.Packages.md) 242 | 243 | 8. [Creating Functions](https://github.com/FCrSTATS/R_basics/blob/master/8.Functions.md) 244 | 245 | 9. [Random Numbers with Expected Goals](https://github.com/FCrSTATS/R_basics/blob/master/9.RandomExpectedGoals.md) 246 | 247 | 248 | --------------------------------------------------------------------------------