-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlab.Rmd
1618 lines (1133 loc) · 42.8 KB
/
lab.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Introduction To R"
author: "Practise exercises"
output:
bookdown::html_document2:
toc: true
toc_float: true
toc_depth: 3
number_sections: true
theme: flatly
highlight: textmate
df_print: paged
code_folding: "none"
self_contained: false
keep_md: false
encoding: 'UTF-8'
css: "assets/lab.css"
---
```{r,echo=FALSE,child="assets/header-lab.Rmd"}
```
<img src="assets/logo.svg" alt="logo" class="trlogo">
<br>
# Topics
This tutorial aims to get you started with R. It roughly covers the following topics:
- R & RStudio environment
- Running code, scripting, sourcing script
- Variables and operators
- Data types & data type conversion
- Reusing code using functions
- Base and grid graphics
- Input & output of text & graphics
- Reproducible analyses, Rmarkdown, notebooks and reports
- Tidyverse: Modern R programming paradigm
# What? Why R?
This is the definition provided by [R-Project](https://www.r-project.org/about.html).
> R is a language and environment for statistical computing and graphics.
**Pros**
- Data analysis
- Statistics
- High quality graphics
- Huge number of packages
- R is popular
- Reproducible research
- RStudio IDE
- FREE! Open source
**Cons**
- Steep learning curve
- Not elegant/consistent
- Slow
# Getting started
R can be installed from [r-project.org](https://cloud.r-project.org/) for Windows, Mac or Linux operating systems. It is also necessary to install Rtools from [here](https://cran.r-project.org/bin/) for building packages from source when installing new packages.
RStudio is one of the best IDE (Integrated development environment) out there for any language. Download [here](https://www.rstudio.com/products/rstudio/download/) for Windows, Mac or Linux. Rstudio provides you with an environment for organising your R projects, files and outputs. You also get debugging tools and GUI interfaces to common basic operations.
![](images/rstudio-ide.png)
R commands are excecuted and results and returned in the **Console**. The **Console** shows a `>` symbol meaning that it is ready to accept commands. When it is waiting for further information, it shows a `+` symbol. This can happen when you have pasted in partial command or forgot to close parenthesis etc. Provide the required information, complete the command or press <kbd>Esc</kbd> on the keyboard to exit from the `+` back to the `>`.
Run a command in the R console.
```{r,eval=FALSE}
getwd()
```
This command prints the current working directory. When you read or write, this is the path that R looks for.
Commands written in the **Console** are executed and lost. R commands can be saved as a script. To create a new script, go to **File > New File > R Script**. This text file can be saved to the working directory named **script.R**. Now add some R command to the file. For example try;
```{r}
date()
```
While in an R script, select the text or place the cursor on that line and click **Run**. Alternatively use keyboard shortcut <kbd>Ctrl</kbd>+<kbd>Enter</kbd> / <kbd>Command</kbd>+<kbd>Enter</kbd>.
`date()` prints the current system date. Or you could try `SessionInfo()` which gives you a summary of the current system setup including R version, operating system and R packages that are loaded/attached.
Then save the file as, for example **script.R**. All commands in the saved **script.R** can be run as a batch either by selecting all the commands followed by **Run** / <kbd>Ctrl</kbd>+<kbd>Enter</kbd>, or directly sourcing the file from the console like this:
`source("script.R")`
# Variables & Operators
Variables are used to store values. Variables can store many different kinds of data as will be covered under data types. Variables can be pretty much any string. When creating variables, it is important that they do not override existing variable or function names and this can create issues further on.
- Avoid conflicting variable names like `c`, `t` ,`q` etc
- Variable names cannot start with a number
## Basic Operators
Variables are assigned usually using the `<-` operator. The `=` operator also works in a similar way for most part.
```{r}
x <- 4
x = 4
x
```
The commonly used arithmetic operators are shown below returning a number.
```{r}
x <- 4
y <- 2
# add
x + y
# subtract
x - y
# multiply
x * y
# divide (get quotient after division)
x / y
# modulus (get reminder after division)
x %% y
# power
x ^ y
```
## Logical Operators
Logical operators return a logical `TRUE` or `FALSE`.
```{r}
# equal to?
x == y
# not equal to?
x != y
# greater than?
x > y
# less than?
x < y
# greater than or equal to?
x >= y
# less than or equal to?
x <= y
```
The OR operator `|` and the AND operator `&` is useful when dealing with logical statements.
```{r}
(x > y) | (y < x)
(x > y) & (y < x)
```
`|` and `&` are vectorised which means it can be applied to two logical vectors. Each pair is compared and a result is produced for each element. The result is a vector.
```{r}
c(F,F,F,T,F,F) | c(F,F,F,F,F,F)
```
Now, there are also two variants `||` and `&&`. These operators compare left to right element-wise and stop after the first element. Consider the same example above replacing `|` with `||`. The result is one element and not a vector.
```{r}
c(F,F,F,T,F,F) || c(F,F,F,F,F,F)
```
The `||` operator may not be always desirable as it only compares the first element in both vectors to return the result.
```{r}
c(F,F,F,T,F,F) | c(F,F,F,F,NA,F)
c(F,F,F,T,F,F) || c(F,F,F,F,NA,F)
```
The longer operators also only evaluate as many terms as needed (short-circuiting). A positive side-effect of this is that if some of elements are `NULL`, it still returns a result.
```{r}
T | NULL
T || NULL
```
In the second case, the first part was `TRUE`, so it did not evaluate the second part which is a `NULL`. But if `&&` was used, it will have to evaluate both sides and that would return an error.
In practice, the long operators are not commonly used. A better practice is to use `any()` and `all()` to evaluate logical vectors to a single logical.
```{r}
# are any of these true?
any(c(F,F,F,T,F,F))
```
```{r}
# are all of these true?
all(c(F,F,F,T,F,F))
```
Characters/strings can be assigned to variables in a similar manner.
```{r}
z <- "this"
z1 <- "that"
paste(z,z1)
```
The function `paste()` concatenates strings.
Variables names must be selected such that they do not conflict with existing variables/functions. For example, variable name `c` must be avoided as it is an existing function to concatenate R objects. The variable name `t` must be avoided as it is a function to transpose a matrix. Variable names must not start with a number.
## Other Operators
Here are some other commonly used operators. `:` is used generate a sequence.
```{r}
1:10
```
`%in%` is a set operator. `"a" %in% c("x","p","a","c")` checks if `a` is a member of the set `x,p,a,c`.
```{r}
"a" %in% c("x","p","a","c")
```
The reverse would also work, but the number of returned elemnts are now different.
```{r}
c("x","p","a","c") %in% "a"
```
And here are some operators that are not so commonly used.
`::` is used to access a function explicitly from a specific package. When you normally call a function, say `sum()`, R searches the namespace and finds it. In case, there is a function `sum()` from another package, the last loaded package overrides the previous function. In cases like this or to be absolutely sure that you are using the correct function from the correct package, you can use `package::function()` to call a function. For example; `base::sum()`. `:::` is used to call functions from a package that are not "exported". This is rarely used.
`%*%` is used for matrix multiplication.
```{r}
matrix(c(2,2,3,3),nrow=2) %*% matrix(c(4,2,5,3),nrow=2)
matrix(c(2,2,3,3),nrow=2) %*% c(6,6)
```
<div class="boxy">
<b><i class="fas fa-clipboard-list"></i> Challenge</b>
Can you write the code to find and print even numbers from a vector of numbers, say 1 to 10? The output being `2 4 6 8 10`. *Click below to reveal the code.*
<p>
<button class="btn btn-sm btn-primary btn-collapse btn-collapse-normal collapsed" type="button" data-toggle="collapse" data-target="#task-operators" aria-expanded="false" aria-controls="task-operators">
</button>
</p>
<div class="collapse" id="task-operators">
<div class="card card-body">
```{r}
x <- c(1:10)
y <- x %% 2
z <- y==0
x[z]
```
<i class="fas fa-lightbulb"></i> More explanation?
`c(1:10)`creates a vectors of numbers 1 to 10. `x %% 2` gets the modulus of these numbers (ie; divide by 2 and get the reminder). `y==0` checks if the reminders are zero. Returns a `TRUE` if it's zero or a `FALSE` if not. `z` is now a logical vector. `z` can be used to index `x`. `x[z]` returns values of x that are true.
This can all be written in one line as well `c(1:10)[c(c(1:10) %% 2)==0]`.
</div>
</div>
</div>
# Data Types
## Overview
Overview of data structures in R
```{r,echo=FALSE}
data.frame(dimension=c("1D","2D","nD"),homogenous=c("Atomic vector","Matrix","Array"),heterogenous=c("List","Dataframe",""))
```
R data object that have a single type of data are referred to as homogenous data type. These are also called atomic types. Heterogenous objects have mixed data types.
## Homogenous data
### Basic
The mode of a variable is inspected using the function `mode()`. Here we can see some of the basic data objects in R.
```{r}
mode(1.0)
mode(1L)
mode("hello")
mode(factor(1))
mode(T)
```
Factors are explained further below. The type of a variable can be inspected using the function `typeof()`.
```{r}
typeof(1.0)
typeof(1L)
typeof("hello")
typeof(factor(1))
typeof(T)
```
Other useful functions for inspecting R objects.
```{r}
class(x)
str(x)
structure(x)
```
### Vectors
Vectors store multiple values. Multiple values, variables and vectors are concatenated together using the function `c()`.
```{r}
x <- c(2,3,4,5,6)
y <- c("a","c","d","e")
x
y
```
There are different ways to create vectors. Here are a few:
```{r}
c(2,3,5,6)
2:8
seq(2,5,by=0.5)
rep(1:3,times=2)
rep(1:3,each=2)
```
R uses 1-based indexing system and a specific value from a specific location in the vector is accessed using the `[]` operator.
```{r}
x[1]
y[3]
```
The `c()` function can be used to specify multiple positions.
```{r}
x[c(1,3)]
```
The above vector is 1-dimensional and composed of the same data type (homogenous). Such vectors are referred to as atomic vectors.
```{r}
mode(x)
mode(y)
str(x)
str(y)
```
Vectors can be added or concatenated directly. This is referred to as a vectorised operation, a crucial concept in R.
```{r}
x <- c(2,3,4,5)
y <- c(9,8,7,6)
x+y
z <- c("a","an","a","a")
k <- c("boy","apple","girl","mess")
paste(z,k)
```
Verify if an R object is atomic (contains a single data type).
```{r}
is.atomic(x)
```
```{r}
is.numeric(x)
is.character(z)
```
A vector of logical type is called a logical vector.
```{r}
x <- c(T,F,T,T)
is.logical(x)
```
Vectorised logical operations can be performed on logical vectors.
```{r}
c(F,T,F,F) | c(F,F,F,F)
c(F,T,F,F) & c(F,F,F,F)
```
Vectors can be named if required.
```{r}
x <- c("a"=2,"b"=3,"c"=8)
x
```
Named vectors can be subsetted using the name.
```{r}
x["c"]
```
### Factors
Factors are vectors that store categorical data.
```{r}
x <- factor(c("a","b","b","c","c"))
x
class(x)
str(x)
```
Factor 'x' has 3 categories or in R speak; 3 levels.
```{r}
levels(x)
```
The levels are ordered automatically in alphabetical order as seen above. The order can be manually set.
```{r}
factor(c("a","b","b","c","c"),levels=c("b","a","c"))
```
Verify if an R object is a factor.
```{r}
is.factor(x)
```
### Matrix
Vectors can be assembled into a matrix data structure.
```{r}
x <- matrix(c(2,3,4,5,6,7))
x
```
A matrix is a 2D data structure with rows and columns.
```{r}
# dimensions
dim(x)
# number of rows
nrow(x)
# number of columns
ncol(x)
```
The number of rows and columns can be specified when building the matrix. The matrix can be filled up row-wise (`byrow=T`) or colum-wise (`byrow=F`).
```{r}
x <- matrix(c(2,3,4,5,6,7),nrow=3,ncol=2,byrow=TRUE)
x
```
```{r}
str(x)
```
Verify if an R object is a matrix.
```{r}
is.matrix(x)
```
Matrix positions can be accessed using the `[]` operator by specifying the row and column `[row,col]`.
```{r}
x[2,2]
```
A whole row or a column can be accessed by `[row,]` or `[,col]`.
```{r}
x[1,]
x[,2]
```
Notice that this automatically creates a vector. The matrix data type can be retained by specifying `drop=FALSE`.
```{r}
x[1,,drop=F]
x[,2,drop=F]
```
Column names and row names can be added to matrices.
```{r}
rownames(x) <- c("a","b","c")
colnames(x) <- c("k","p")
```
Then the matrix can be accessed using these labels.
```{r}
x["b",]
x[,"p"]
```
<div class="boxy">
<b><i class="fas fa-clipboard-list"></i> Challenge</b>
If I create a vector as follows `x <-c(5,3,9,"6")`, what is the "type" of the element in the third position? Is it a number?
<p>
<button class="btn btn-sm btn-primary btn-collapse btn-collapse-normal collapsed" type="button" data-toggle="collapse" data-target="#task-vectors" aria-expanded="false" aria-controls="task-vectors">
</button>
</p>
<div class="collapse" id="task-vectors">
<div class="card card-body">
```{r}
x <-c(5,3,9,"6")
typeof(x[3])
```
<i class="fas fa-lightbulb"></i> The third position is not a number, it's a character. In fact, all elements in this vector are characters. If there is a character in a numeric vector, all elements are converted to characters (`typeof(x)`).
</div>
</div>
</div>
<div class="boxy">
<b><i class="fas fa-clipboard-list"></i> Challenge</b>
Create the matrix shown below and extract the third column as a vector.
```{r,echo=FALSE}
matrix(c(2,3,4,5,2,7,6,6,6),nrow=3,byrow=T)
```
<p>
<button class="btn btn-sm btn-primary btn-collapse btn-collapse-normal collapsed" type="button" data-toggle="collapse" data-target="#task-matrix" aria-expanded="false" aria-controls="task-matrix">
</button>
</p>
<div class="collapse" id="task-matrix">
<div class="card card-body">
```{r}
# either this
x <- matrix(c(2,3,4,5,2,7,6,6,6),nrow=3,byrow=T)
# or this
x <- matrix(c(2,5,6,3,2,6,4,7,6),nrow=3,byrow=F)
x
```
```{r}
# access third column
x[,3]
```
</div>
</div>
</div>
## Heterogenous data
### Lists
List elements can be mixed data type and is built using `list()` rather than `c()`.
```{r}
x <- list(c(2,3,4,5),c("a","b","c","d"),factor(c("a","a","b")),
matrix(c(3,2,3,5,6,7),ncol=2))
x
```
```{r}
typeof(x)
class(x)
```
```{r}
str(x)
```
Lists are recursive as there can be lists inside lists.
```{r}
str(list(list(list(list()))))
```
Verify if an R object is a list.
```{r}
is.list(x)
```
List are accessed using `[]` and `[[]]`. `[]` returns a list while `[[]]` returns the object inside the list.
```{r}
x[1]
```
```{r}
x[1:2]
class(x[1:2])
```
```{r}
x[[4]]
class(x[[4]])
```
List items can also be named. Let's add a list into our list.
```{r}
x$newlist <- list(c(500,600,700))
x
```
Lists can be accessed by the name.
```{r}
x$newlist
```
Use `unlist()` to remove the list structure.
```{r}
unlist(x$newlist)
```
### data.frame
data.frames are the most common way to store data in R. dataframes are basically lists of equal-length vectors. Like matrices, dataframe 2D with rows and columns. data.frames are created using the function `data.frame()`. The most important difference between a matrix and a data.frame is that matrices are atomic (contains data of one type) while data.frames can contain a mix of numeric columns, characters, factors, logicals etc.
```{r,results="markup"}
dfr <- data.frame(x = 1:3, y = c("a", "b", "c"))
print(dfr)
```
Notice that we have named the columns as 'x' and 'y'.
```{r}
str(dfr)
```
Notice that column 'y' has been automatically converted to a factor. This is the root of a lot of issues for new R users. It is best to avoid the automatic conversion by setting `stringsAsFactors=FALSE`.
```{r}
dfr <- data.frame(x = 1:3, y = c("a", "b", "c"), stringsAsFactors = F)
str(dfr)
```
Verify if an R object is a 'data.frame'.
```{r}
is.data.frame(dfr)
```
Accessing positions in a data.frame is similar to matrices. In addition, the `$` operator is also commonly used to access a column.
```{r}
dfr$x
dfr$y
```
Subset a `data.frame()` conditionally.
```{r,results="markup"}
print(subset(dfr,dfr$y=="a"))
```
Get column names and row names of a data.frame
```{r}
colnames(dfr)
rownames(dfr)
```
Ordering a dataframe by one column in decreasing order.
```{r,results="markup"}
print(dfr[order(dfr$y,decreasing=T),])
```
## Type conversion
Several functions are available to convert R objects from one type to another.
```{r}
x <- c(1,2,3)
str(x)
```
```{r}
y <- as.character(x)
str(y)
```
The numeric vector has been converted to a character vector. Similarly, character can be coerced (if possible) into numbers.
```{r}
x <- c("1","2","hello")
str(x)
```
```{r}
str(as.numeric(x))
```
Notice that characters that cannot be converted to a valid number is converted to NA along with a warning message.
<div class="boxy">
<b><i class="fas fa-clipboard-list"></i> Challenge</b>
Here is a data.frame inside a list which is inside a list. How do you extract the *Species* column as a vector?
```{r,echo=FALSE}
x <- list(list(head(iris)))
str(x)
```
<p>
<button class="btn btn-sm btn-primary btn-collapse btn-collapse-normal collapsed" type="button" data-toggle="collapse" data-target="#task-dfr" aria-expanded="false" aria-controls="task-dfr">
</button>
</p>
<div class="collapse" id="task-dfr">
<div class="card card-body">
```{r}
x <- list(list(head(iris)))
# either this
x[[1]][[1]]$Species
# or this
x[[1]][[1]][,5]
```
`[]` access a list but still returns a list. `[[]]` returns the object inside a list.
</div>
</div>
</div>
# Functions
Functions are chunks of code packaged into reusable units. We have used many functions in the previous sections such as `c()`, `str()`, `is.list()`, `typeof()` etc.
## Built-In
Functions that come with the base R installation are referred to as built-in functions or base functions. R has loads of built-in functions for various applications such as data analysis, programming, math, plotting etc. Additional functions can be made available by installing external packages.
Below are some functions that can be applied to numeric data:
```{r}
# generate 10 random numbers between 1 and 200
x <- sample(x=1:200,10)
# length
length(x)
# sum
sum(x)
# mean
mean(x)
# median
median(x)
# min
min(x)
# log
log(x)
# exponent
exp(x)
# square-root
sqrt(x)
# round
round(x)
# sort
sort(x)
```
Some useful string functions.
```{r}
a <- "sunny"
b <- "day"
# join
paste(a, b)
# find a pattern
grep("sun", a)
# number of characters
nchar("sunny")
# to uppercase
toupper("sunny")
# to lowercase
tolower("SUNNY")
# replace pattern
sub("sun", "fun", "sunny")
# substring
substr("sunny", start=1, stop=3)
```
Some general functions
```{r}
print("hello")
print("world")
cat("hello")
cat(" world")
cat("\nhello\nworld")
```
## Custom
If you see yourself copy-pasting a chunk of R code many times, then it is probably a good idea to create a function out of it.
Let's say you have two vectors that you would like to perform a series of operations on and then output a result.
```{r}
a <- 1:6
b <- 8:10
d <- a*b
e <- log(d)
f <- sqrt(e)
f
```
You can modify this code block into a function as follows:
```{r}
my_function <- function(a, b){
d <- a*b
e <- log(d)
f <- sqrt(e)
return(f)
}
```
Once defined, you can use this wherever needed.
```{r}
my_function(a=2:4, b=6:8)
```
**a** and **b** are called arguments or parameters to the function. If they are explicity written, then the position defines which parameter they are.
```{r}
# this
my_function(a=2:4, b=6:8)
# is the same as this
my_function(b=2:4, a=6:8)
# and the same as this
my_function(2:4, 6:8)
```
In this case `my_function(2:4,6:8)`, argument **a** is `2:4` and argument **b** is `6:8`. In this case `my_function(6:8,2:4)`, argument **a** is `6:8` and argument **b** is `2:4`.
Variables defined within a function are only available within that function and not available outside that function unless returned.
```{r,error=TRUE}
my_new_function <- function(a) {
varz <- a + 2
return(varz)
}
my_new_function(5)
print(varz)
```
In the above function, variable `varz` created inside the function is not available outside of that function.
But the reverse is possible.
```{r}
my_new_function <- function() {
varz <- foo + 2
return(varz)
}
foo <- 55
my_new_function()
```
In the example above, variable `foo` used inside the function is not supplied to the function through an argument, yet it still manages to find it. When a function doesn't find a variable inside a function, it searches outside the function.
<div class="boxy">
<b><i class="fas fa-clipboard-list"></i> Challenge</b>
R lacks a function to compute coefficient of variation (COV). Create a function to compute the COV. And use the function to compute the COV of these set of values: `c(4,7,2,3,5,4,3)`. The formula for COV is `cov=sd/mean`. Remember to NOT use `cov` as the function name because it already exists (`?cov`). It stands for covariance. So, use another function name.
<p>
<button class="btn btn-sm btn-primary btn-collapse btn-collapse-normal collapsed" type="button" data-toggle="collapse" data-target="#task-cov" aria-expanded="false" aria-controls="task-cov">
</button>
</p>
<div class="collapse" id="task-cov">
<div class="card card-body">
```{r}
cova <- function(x) sd(x)/mean(x)
cova(c(4,7,2,3,5,4,3))
```
</div>
</div>
</div>
# Control Structures
Conditional statements are written using `if()`.
```{r}
a <- 2
b <- 5
if(a < b) print(paste(a,"is smaller than",b))
```
`else` is used to add an alternative output.
```{r}
a <- 2
b <- 5
if(a < b) {
print(paste(a,"is smaller than",b))
}else{
print(paste(b,"is smaller than",a))
}
a <- 60
b <- 10
if(a < b) {
print(paste(a,"is smaller than",b))
}else{
print(paste(b,"is smaller than",a))
}
```
`if else` statements can be chained together:
```{r}
grade <- "B"
if(grade == "A"){
print("Grade is Excellent!")
}else if(grade == "B"){
print("Grade is Good.")
} else if (grade == "C") {
print("Grade is Alright.")
}
```
This is not to be confused with a function called `ifelse()`. This is also used for conditional selection and takes the form `ifelse(test, return-if-yes, return-if-no)`, and this is vectorised. So, for example, here are some ages of persons. Classify them as adults or juveniles.
```{r}
x <- c(6,23,12,10,56,44)
ifelse(x>18,"Adult","Juvenile")
```
The `for()` loop is useful to run commands repeatedly over a known number of iterations.
```{r}
for (i in 1:5){
print(i)
}
```