library(knitr)
# opts_knit$set(out.format = "latex")
knit_theme$set(knit_theme$get("greyscale0"))

options(replace.assign = FALSE, width = 50)

opts_chunk$set(fig.path = "figure/graphics-", 
               cache.path = "cache/graphics-", 
               fig.align = "center", 
               dev = "pdf", fig.width = 5, fig.height = 5, 
               fig.show = "hold", cache = FALSE, par = TRUE)
knit_hooks$set(crop = hook_pdfcrop)

knit_hooks$set(par = function(before, options, envir) {
  if (before && options$fig.show != "none") {
    #par(mar=c(3,3,2,1),cex.lab=.95,cex.axis=.9, mgp=c(2,.7,0),tcl=-.01, las=1)
  }}, crop = hook_pdfcrop)

The aim of this practical is to review our knowledge of functions, for loops and if statements.

Basic functions

Consider the following simple function

v = 5
Fun1 = function() {
  v = 0
  return(v)
}
Fun1()
  1. Why does the final line return 0 and not 5. r ## Fun1 uses the local variable v
  2. Delete line 3 in the above piece of code. Now change Fun1() to allow v to be passed as an argument, i.e. we can write Fun1(5). Call this function to make sure it works.

    r Fun1 = function(v) { return(v) } Fun1(10)

Default arguments:

Fun2 = function(x = 10) {
  return(x)
}

Fun3 = function(x) {
  return(x)
}
  1. Why does r Fun2() work, but this raises an error r Fun3()

    ```r

    Fun3 expects an argument x, but

    we haven't given one and there is

    no default.

    ```

  2. Change Fun2 so that it returns x*x.

    r Fun2 = function(x = 10) { return(x * x) }

if statements.

Fun4 = function(x) {
  if (x == 5) {
    y = 0
  } else {
    y = 1
  }
  return(y)
}

Change Fun4 so that it:

Change Fun4() so it errors if $x$ is positive

```r
Fun4 = function(x) {
  rtn_value = 0
  if (x > 0) {
    stop("This function requires x <= 0")
  } else if (x < 0) {
    rtn_value = -1
  }
  return(rtn_value)
}
```

for loops.

total = 0
for (i in 1:5) {
  total = total + i
}
total

The for loop above calculates [ \sum_{i=1}^5 i = 1 + 2 + 3 + 4 + 5 ]

  1. What is the final value of total in the above piece of code? r total
  2. Change the above loop to calculate the following summations: [ \mbox{(i)} \sum_{i=1}^{20} (i+1)
    ]

    r total = 0 for (i in 1:20) { total = total + (i + 1) } total

[ \mbox{(ii)} \sum_{j=-10}^{15} j ]

```r
total = 0
for (j in-10:15) {
  total = total + j
}
total
```
  1. Rewrite the two loops using the sum() function. For example, the for loop in the first example can be written as sum(1:5)

    r sum(2:21) sum(-10:15)

More functions, for loops and signalling conditions:

a = 2
total = 0
for (blob in a:5) {
  total = total + blob
}
  1. In the code above, delete line 1. Now put the above code in a function called Fun5, where a is passed as an argument, i.e. we can call Fun5(1)

    r Fun5 = function(a) { total = 0 for (blob in a:5) { total = total + blob } return(total) } Fun5(1)

  2. Alter the code so that the for loop goes from a to b, rather than a to $5$. Allow b to be passed as an argument, i.e. we can call Fun5(1,5). r Fun5 = function(a, b) { total = 0 for (blob in a:b) { total = total + blob } return(total) } Fun5(1, 5)

  3. Change Fun5 so that it has default arguments of a = 1 and b = 10.

    r Fun5 = function(a = 1, b = 10) { total = 0 for (blob in a:b) { total = total + blob } return(total) } Fun5(5)

  4. Change Fun5 so that it messages the user the total after each iteration and stops the function if the total has surpassed 50.

    r Fun5 = function(a = 1, b = 10) { total = 0 for (blob in a:b) { total = total + blob message("Current total is ", total) if (total > 50) { stop("Total has surpassed limit of 50") } } return(total) } Fun5(5)

Solutions

The solutions can be viewed via

library("jrAdvPackage")
vignette("solutions1", package = "jrAdvPackage")


jr-packages/jrAdvPackage documentation built on Dec. 27, 2019, 8:05 a.m.