Programming in R

Nikhil Kaza

2024-08-18

Agenda

  • Functions

Avoid Repeating Code

# create dummy data
library(tidyverse)

city <- tibble(
  porto = rnorm(100),
  aberdeen = rnorm(100),
  nairobi = c(rep(NA, 10), rnorm(90)),
  genoa = rnorm(100)
)

glimpse(city)
Rows: 100
Columns: 4
$ porto    <dbl> -0.89820122, -0.64065598, 1.00912047, 0.31865785, -0.69208465…
$ aberdeen <dbl> 0.27463936, 0.19410247, -0.77222739, 1.61587528, 0.67944043, …
$ nairobi  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -0.34498423, 0.203135…
$ genoa    <dbl> 0.10048172, -1.66604523, -0.16956561, 0.63894205, 0.19617721,…
# Create a new function to multiply two vectors together
multiply_columns <- function(x,y){return(x*y)}

multiply_columns(x = city$porto, y = city$aberdeen) %>% head(5)
[1] -0.2466814 -0.1243529 -0.7792705  0.5149113 -0.4702303
multiply_columns(x = city$nairobi, y = city$aberdeen) %>% head(5)
[1] NA NA NA NA NA

Use it in Mutate

city %>%
    mutate(por_aber = multiply_columns(x = porto, y = aberdeen),
           nai_aber = multiply_columns(x = nairobi, y = aberdeen))
# A tibble: 100 × 6
     porto aberdeen nairobi   genoa por_aber nai_aber
     <dbl>    <dbl>   <dbl>   <dbl>    <dbl>    <dbl>
 1 -0.898    0.275       NA  0.100   -0.247        NA
 2 -0.641    0.194       NA -1.67    -0.124        NA
 3  1.01    -0.772       NA -0.170   -0.779        NA
 4  0.319    1.62        NA  0.639    0.515        NA
 5 -0.692    0.679       NA  0.196   -0.470        NA
 6  0.239    0.549       NA  0.620    0.131        NA
 7  0.0206  -0.852       NA -1.18    -0.0175       NA
 8 -1.40    -0.660       NA -1.23     0.924        NA
 9  1.20     0.0311      NA  0.477    0.0375       NA
10  1.27     0.544       NA  0.0947   0.691        NA
# ℹ 90 more rows

Edge Cases are important

  • Producing Errors and Warnings are good practise.
  • Test for things that might produce unexpected results.
divide_columns <- function(x, y) {

if(any(y==0)){
    warning("Division by 0 is likely. You should expect to see a NAN")
}

  temp_var <- x / y
  
  if (any(is.na(temp_var))) {
    warning("The function has a produced NA")
    return(temp_var)
  } else {
    return(temp_var)
  }
}

divide_columns(x = city$nairobi, y = city$aberdeen) %>% head(5)
Warning in divide_columns(x = city$nairobi, y = city$aberdeen): The function
has a produced NA
[1] NA NA NA NA NA
divide_columns(x = rep(0,100), y = city$aberdeen) %>% head(5)
[1] 0 0 0 0 0
divide_columns(x=city$nairobi, y=rep(0,100)) %>% head(5)
Warning in divide_columns(x = city$nairobi, y = rep(0, 100)): Division by 0 is
likely. You should expect to see a NAN
Warning in divide_columns(x = city$nairobi, y = rep(0, 100)): The function has
a produced NA
[1] NA NA NA NA NA

Logial Operators

  • & : Element Wise AND
v <- c(3,1,3,5L)
t <- c(4,1,NA,5.0001)

v>=3 & t>=4
[1]  TRUE FALSE    NA  TRUE
  • &&: Logical AND (Only use it on a scalars)
any(is.na(v)) && any(is.na(t))
[1] FALSE
  • : Element Wise OR
v>=3 | t>=4
[1]  TRUE FALSE  TRUE  TRUE
  • ||: Logical OR (Only use it on a scalars)
any(is.na(v)) || any(is.na(t))
[1] TRUE

&& and || are often used in if functions for controlling the logic

Loops

temp <- list()

i <- 1
while (i<ncol(city)-1) {
  temp[[i]] <- multiply_columns(x = city[, i], y = city[, i + 1])
  i <- i+1
}
 
temp
[[1]]
            porto
1   -2.466814e-01
2   -1.243529e-01
3   -7.792705e-01
4    5.149113e-01
5   -4.702303e-01
6    1.313525e-01
7   -1.750259e-02
8    9.242714e-01
9    3.748486e-02
10   6.911366e-01
11   5.110948e+00
12   3.322370e-01
13  -1.946853e+00
14  -4.439492e-01
15  -3.358671e-01
16   2.204048e-01
17  -7.187809e-01
18  -1.035936e+00
19   2.210570e-01
20  -1.085482e+00
21  -7.284394e-01
22   1.268003e-02
23  -2.154665e-02
24   1.578795e-01
25  -2.304444e+00
26   7.159361e-01
27   4.987860e-01
28   2.989732e-03
29   1.139835e+00
30  -1.954144e+00
31   5.891860e-01
32  -1.094534e+00
33   7.017505e-03
34   2.384396e-02
35   6.646473e-01
36  -1.668298e+00
37  -2.605373e-01
38   3.278053e+00
39   4.447801e-01
40  -2.440658e-01
41  -1.428758e-01
42   3.155067e-02
43   8.536880e-01
44  -6.754075e-02
45   4.401237e-01
46  -2.939706e-01
47  -9.763737e-01
48   6.796396e-01
49  -2.145538e-01
50   2.094467e-01
51   3.810799e-02
52   1.877339e-02
53  -1.257112e+00
54  -3.562743e-01
55  -1.441074e-01
56  -1.278814e-01
57  -8.470452e-01
58   3.253081e-01
59   2.830056e+00
60  -1.115530e+00
61   7.276070e-01
62   2.978003e-01
63   4.380176e-02
64   2.937457e-01
65   2.779155e+00
66   8.311259e-02
67  -7.929477e-01
68  -1.877396e-01
69   3.456111e-01
70   2.944756e+00
71  -2.432525e-01
72  -6.215661e-02
73   9.040953e-02
74  -4.017000e-02
75   2.615399e-01
76   2.055250e-01
77  -2.676222e-01
78   8.984744e-01
79  -9.713072e-01
80  -3.720027e-02
81   1.473685e+00
82  -6.966510e-01
83   6.294567e-01
84  -4.293629e-02
85  -3.158663e-01
86  -1.072782e+00
87  -7.779139e-03
88  -1.930981e-01
89   2.167003e+00
90   3.159490e-01
91  -7.546157e-01
92  -1.873771e-05
93   7.314495e-01
94   3.162646e-01
95   2.022600e-02
96  -3.144295e-01
97   1.120044e+00
98  -4.270736e-01
99  -1.507200e-01
100 -1.354211e+00

[[2]]
        aberdeen
1             NA
2             NA
3             NA
4             NA
5             NA
6             NA
7             NA
8             NA
9             NA
10            NA
11  -1.188197269
12  -0.110015114
13   0.563868511
14   0.005452688
15   0.776124541
16  -0.006717992
17   0.870677374
18  -0.767548775
19  -0.811199722
20  -0.069134630
21   1.017214034
22  -1.256842662
23   1.452420788
24   0.219713086
25   2.597598301
26   0.622860922
27   0.554669335
28  -0.018237676
29   1.060380375
30  -1.355582906
31   1.774251498
32   0.158036449
33   0.039134106
34   0.050200877
35   0.051069330
36   0.491565196
37  -0.780577545
38  -2.300623953
39  -0.859605858
40  -0.130119746
41   0.300101736
42   0.807471304
43  -1.338960058
44  -0.080199768
45   0.071278053
46  -0.356066477
47  -0.594688732
48  -1.863852301
49   0.214738063
50  -0.663618876
51  -0.662700962
52  -0.032396095
53  -0.064127614
54  -0.817079839
55  -3.660805523
56  -0.646352155
57   0.167698600
58  -1.714536356
59   1.568046010
60  -1.067856104
61  -0.517090805
62   0.081600601
63   0.040975202
64  -0.048145938
65  -0.302354320
66  -0.252463395
67   1.159456065
68  -0.707924742
69  -0.077359313
70   1.863594319
71  -0.287080089
72   0.004981416
73   0.062292311
74  -0.106599040
75   1.160263157
76  -0.112030347
77   2.021703814
78   1.111189058
79  -0.979442314
80  -0.337421213
81   0.995953396
82   0.146880699
83   0.266931553
84  -0.199686253
85  -0.670782556
86  -1.104170103
87  -0.050397108
88   0.245964790
89  -0.018474243
90   0.301944841
91  -0.824856655
92  -0.128043144
93  -0.278132647
94   0.807522897
95   0.054056251
96  -0.312901746
97   0.359441337
98   0.448150744
99  -0.219582644
100  0.128201045

Loops

temp <- list()
for (i in 1:(ncol(city) - 1)) {
  temp[[i]] <- multiply_columns(x = city[, i], y = city[, i + 1])
}

temp
[[1]]
            porto
1   -2.466814e-01
2   -1.243529e-01
3   -7.792705e-01
4    5.149113e-01
5   -4.702303e-01
6    1.313525e-01
7   -1.750259e-02
8    9.242714e-01
9    3.748486e-02
10   6.911366e-01
11   5.110948e+00
12   3.322370e-01
13  -1.946853e+00
14  -4.439492e-01
15  -3.358671e-01
16   2.204048e-01
17  -7.187809e-01
18  -1.035936e+00
19   2.210570e-01
20  -1.085482e+00
21  -7.284394e-01
22   1.268003e-02
23  -2.154665e-02
24   1.578795e-01
25  -2.304444e+00
26   7.159361e-01
27   4.987860e-01
28   2.989732e-03
29   1.139835e+00
30  -1.954144e+00
31   5.891860e-01
32  -1.094534e+00
33   7.017505e-03
34   2.384396e-02
35   6.646473e-01
36  -1.668298e+00
37  -2.605373e-01
38   3.278053e+00
39   4.447801e-01
40  -2.440658e-01
41  -1.428758e-01
42   3.155067e-02
43   8.536880e-01
44  -6.754075e-02
45   4.401237e-01
46  -2.939706e-01
47  -9.763737e-01
48   6.796396e-01
49  -2.145538e-01
50   2.094467e-01
51   3.810799e-02
52   1.877339e-02
53  -1.257112e+00
54  -3.562743e-01
55  -1.441074e-01
56  -1.278814e-01
57  -8.470452e-01
58   3.253081e-01
59   2.830056e+00
60  -1.115530e+00
61   7.276070e-01
62   2.978003e-01
63   4.380176e-02
64   2.937457e-01
65   2.779155e+00
66   8.311259e-02
67  -7.929477e-01
68  -1.877396e-01
69   3.456111e-01
70   2.944756e+00
71  -2.432525e-01
72  -6.215661e-02
73   9.040953e-02
74  -4.017000e-02
75   2.615399e-01
76   2.055250e-01
77  -2.676222e-01
78   8.984744e-01
79  -9.713072e-01
80  -3.720027e-02
81   1.473685e+00
82  -6.966510e-01
83   6.294567e-01
84  -4.293629e-02
85  -3.158663e-01
86  -1.072782e+00
87  -7.779139e-03
88  -1.930981e-01
89   2.167003e+00
90   3.159490e-01
91  -7.546157e-01
92  -1.873771e-05
93   7.314495e-01
94   3.162646e-01
95   2.022600e-02
96  -3.144295e-01
97   1.120044e+00
98  -4.270736e-01
99  -1.507200e-01
100 -1.354211e+00

[[2]]
        aberdeen
1             NA
2             NA
3             NA
4             NA
5             NA
6             NA
7             NA
8             NA
9             NA
10            NA
11  -1.188197269
12  -0.110015114
13   0.563868511
14   0.005452688
15   0.776124541
16  -0.006717992
17   0.870677374
18  -0.767548775
19  -0.811199722
20  -0.069134630
21   1.017214034
22  -1.256842662
23   1.452420788
24   0.219713086
25   2.597598301
26   0.622860922
27   0.554669335
28  -0.018237676
29   1.060380375
30  -1.355582906
31   1.774251498
32   0.158036449
33   0.039134106
34   0.050200877
35   0.051069330
36   0.491565196
37  -0.780577545
38  -2.300623953
39  -0.859605858
40  -0.130119746
41   0.300101736
42   0.807471304
43  -1.338960058
44  -0.080199768
45   0.071278053
46  -0.356066477
47  -0.594688732
48  -1.863852301
49   0.214738063
50  -0.663618876
51  -0.662700962
52  -0.032396095
53  -0.064127614
54  -0.817079839
55  -3.660805523
56  -0.646352155
57   0.167698600
58  -1.714536356
59   1.568046010
60  -1.067856104
61  -0.517090805
62   0.081600601
63   0.040975202
64  -0.048145938
65  -0.302354320
66  -0.252463395
67   1.159456065
68  -0.707924742
69  -0.077359313
70   1.863594319
71  -0.287080089
72   0.004981416
73   0.062292311
74  -0.106599040
75   1.160263157
76  -0.112030347
77   2.021703814
78   1.111189058
79  -0.979442314
80  -0.337421213
81   0.995953396
82   0.146880699
83   0.266931553
84  -0.199686253
85  -0.670782556
86  -1.104170103
87  -0.050397108
88   0.245964790
89  -0.018474243
90   0.301944841
91  -0.824856655
92  -0.128043144
93  -0.278132647
94   0.807522897
95   0.054056251
96  -0.312901746
97   0.359441337
98   0.448150744
99  -0.219582644
100  0.128201045

[[3]]
         nairobi
1             NA
2             NA
3             NA
4             NA
5             NA
6             NA
7             NA
8             NA
9             NA
10            NA
11   0.496037475
12   0.170526145
13   0.070425378
14   0.013011981
15   2.581125037
16  -0.016481569
17   2.033920193
18   0.484553085
19   0.770706528
20  -0.102444376
21  -0.297426465
22  -0.491927820
23   1.243317592
24  -0.374666155
25   0.158358262
26   1.119182166
27  -0.198628275
28  -0.147389299
29   0.663559531
30  -1.574964972
31  -3.109812472
32   0.197588425
33   0.105962203
34  -0.494181266
35   0.036356382
36   0.419404326
37  -0.902072501
38   1.976372554
39   2.391364638
40   0.547924953
41   0.423952875
42  -0.717445484
43  -0.636858768
44  -0.211854087
45   0.113680248
46   0.279266720
47   0.161858562
48   1.299545310
49  -0.113316930
50   0.597273856
51   1.268819531
52  -0.869988608
53   0.007905452
54  -1.420862962
55   0.632375688
56   0.595617340
57  -0.059490308
58   1.233138806
59  -0.175582884
60  -0.372797750
61  -0.408502614
62   0.106017652
63   2.375054151
64   0.111944152
65   0.037344047
66  -0.397696627
67  -0.409168375
68   0.857304247
69   0.092755469
70  -0.038238169
71   0.025104140
72   0.023389263
73   0.151071616
74   0.286887283
75   0.142844710
76   0.627450375
77   1.257464566
78  -0.349090444
79   0.657417062
80   0.848034208
81   1.321136335
82   0.030647928
83  -1.059050183
84  -0.256689687
85   0.528285886
86  -0.752361872
87  -0.475218269
88  -0.593844134
89  -0.006722801
90  -1.168154159
91   0.149600986
92  -0.750210359
93  -0.517817206
94  -0.398961941
95  -0.680567993
96  -0.034457627
97   0.127112927
98  -0.775755682
99  -2.900133768
100  0.195045050

Loops

map_dfc(1:(ncol(city)-1), function(i){city[,i] * city[,i+1]})
            porto     aberdeen      nairobi
1   -2.466814e-01           NA           NA
2   -1.243529e-01           NA           NA
3   -7.792705e-01           NA           NA
4    5.149113e-01           NA           NA
5   -4.702303e-01           NA           NA
6    1.313525e-01           NA           NA
7   -1.750259e-02           NA           NA
8    9.242714e-01           NA           NA
9    3.748486e-02           NA           NA
10   6.911366e-01           NA           NA
11   5.110948e+00 -1.188197269  0.496037475
12   3.322370e-01 -0.110015114  0.170526145
13  -1.946853e+00  0.563868511  0.070425378
14  -4.439492e-01  0.005452688  0.013011981
15  -3.358671e-01  0.776124541  2.581125037
16   2.204048e-01 -0.006717992 -0.016481569
17  -7.187809e-01  0.870677374  2.033920193
18  -1.035936e+00 -0.767548775  0.484553085
19   2.210570e-01 -0.811199722  0.770706528
20  -1.085482e+00 -0.069134630 -0.102444376
21  -7.284394e-01  1.017214034 -0.297426465
22   1.268003e-02 -1.256842662 -0.491927820
23  -2.154665e-02  1.452420788  1.243317592
24   1.578795e-01  0.219713086 -0.374666155
25  -2.304444e+00  2.597598301  0.158358262
26   7.159361e-01  0.622860922  1.119182166
27   4.987860e-01  0.554669335 -0.198628275
28   2.989732e-03 -0.018237676 -0.147389299
29   1.139835e+00  1.060380375  0.663559531
30  -1.954144e+00 -1.355582906 -1.574964972
31   5.891860e-01  1.774251498 -3.109812472
32  -1.094534e+00  0.158036449  0.197588425
33   7.017505e-03  0.039134106  0.105962203
34   2.384396e-02  0.050200877 -0.494181266
35   6.646473e-01  0.051069330  0.036356382
36  -1.668298e+00  0.491565196  0.419404326
37  -2.605373e-01 -0.780577545 -0.902072501
38   3.278053e+00 -2.300623953  1.976372554
39   4.447801e-01 -0.859605858  2.391364638
40  -2.440658e-01 -0.130119746  0.547924953
41  -1.428758e-01  0.300101736  0.423952875
42   3.155067e-02  0.807471304 -0.717445484
43   8.536880e-01 -1.338960058 -0.636858768
44  -6.754075e-02 -0.080199768 -0.211854087
45   4.401237e-01  0.071278053  0.113680248
46  -2.939706e-01 -0.356066477  0.279266720
47  -9.763737e-01 -0.594688732  0.161858562
48   6.796396e-01 -1.863852301  1.299545310
49  -2.145538e-01  0.214738063 -0.113316930
50   2.094467e-01 -0.663618876  0.597273856
51   3.810799e-02 -0.662700962  1.268819531
52   1.877339e-02 -0.032396095 -0.869988608
53  -1.257112e+00 -0.064127614  0.007905452
54  -3.562743e-01 -0.817079839 -1.420862962
55  -1.441074e-01 -3.660805523  0.632375688
56  -1.278814e-01 -0.646352155  0.595617340
57  -8.470452e-01  0.167698600 -0.059490308
58   3.253081e-01 -1.714536356  1.233138806
59   2.830056e+00  1.568046010 -0.175582884
60  -1.115530e+00 -1.067856104 -0.372797750
61   7.276070e-01 -0.517090805 -0.408502614
62   2.978003e-01  0.081600601  0.106017652
63   4.380176e-02  0.040975202  2.375054151
64   2.937457e-01 -0.048145938  0.111944152
65   2.779155e+00 -0.302354320  0.037344047
66   8.311259e-02 -0.252463395 -0.397696627
67  -7.929477e-01  1.159456065 -0.409168375
68  -1.877396e-01 -0.707924742  0.857304247
69   3.456111e-01 -0.077359313  0.092755469
70   2.944756e+00  1.863594319 -0.038238169
71  -2.432525e-01 -0.287080089  0.025104140
72  -6.215661e-02  0.004981416  0.023389263
73   9.040953e-02  0.062292311  0.151071616
74  -4.017000e-02 -0.106599040  0.286887283
75   2.615399e-01  1.160263157  0.142844710
76   2.055250e-01 -0.112030347  0.627450375
77  -2.676222e-01  2.021703814  1.257464566
78   8.984744e-01  1.111189058 -0.349090444
79  -9.713072e-01 -0.979442314  0.657417062
80  -3.720027e-02 -0.337421213  0.848034208
81   1.473685e+00  0.995953396  1.321136335
82  -6.966510e-01  0.146880699  0.030647928
83   6.294567e-01  0.266931553 -1.059050183
84  -4.293629e-02 -0.199686253 -0.256689687
85  -3.158663e-01 -0.670782556  0.528285886
86  -1.072782e+00 -1.104170103 -0.752361872
87  -7.779139e-03 -0.050397108 -0.475218269
88  -1.930981e-01  0.245964790 -0.593844134
89   2.167003e+00 -0.018474243 -0.006722801
90   3.159490e-01  0.301944841 -1.168154159
91  -7.546157e-01 -0.824856655  0.149600986
92  -1.873771e-05 -0.128043144 -0.750210359
93   7.314495e-01 -0.278132647 -0.517817206
94   3.162646e-01  0.807522897 -0.398961941
95   2.022600e-02  0.054056251 -0.680567993
96  -3.144295e-01 -0.312901746 -0.034457627
97   1.120044e+00  0.359441337  0.127112927
98  -4.270736e-01  0.448150744 -0.775755682
99  -1.507200e-01 -0.219582644 -2.900133768
100 -1.354211e+00  0.128201045  0.195045050

Thank you!