Skip to content

Commit

Permalink
updated function slides
Browse files Browse the repository at this point in the history
  • Loading branch information
RedondoMA committed Oct 17, 2024
1 parent d3ca7c4 commit db1e9dc
Showing 1 changed file with 84 additions and 45 deletions.
129 changes: 84 additions & 45 deletions slide_r_elements_4.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,20 @@ for (i in 1:5) {
```

--

A slight modification of the above example.

```{r for.loop2, echo=T}
for (i in c(2,4,6,8,10)) {
cat(paste('Performing operation on no.', i), '\n')
}
```

The variable `i` <u> takes values </u> from the sequences.
---
name: for_loop_counter

# Repeating actions &mdash; for loop with a counter

Sometimes, we also want an external counter:
To know the current iteration number on the loop, we can set an external counter:

```{r for.loop.cnt, echo=T}
cnt <- 1
Expand Down Expand Up @@ -152,7 +151,7 @@ vec + 1

---
name: vectorization_benchmark

exclude:true
# Repeating actions &mdash; vectorization

Let us compare the time of execution of the vectorized version (vector with 10,000 elements):
Expand All @@ -164,7 +163,6 @@ vec <- vec + 1
proc.time() - ptm # vectorized
```

--

to the loop version:

Expand All @@ -190,17 +188,19 @@ v <- c() # Initialize
for (i in 1:100) {
v <- c(v, i)
}
cat(head(v), " ... ", tail(v))
```

--

It is much better to do it like this:

```{r avoid.growing2, echo=T}
```{r avoid.growing3, echo=T}
v <- rep(NA, 100) # Initialize with length
for (i in 1:100) {
v[i] <- i
}
cat(head(v), " ... ", tail(v))
```

--
Expand Down Expand Up @@ -280,7 +280,51 @@ name: if_clause

# Decisions, an if-clause

Often, one has to take a different course of action depending on a flow of the algorithm. Let's print only odd numbers $[1, 10]$:
Often, one has to take a different course of action depending on a flow of the algorithm.

In R, we use the `if` clause for this purpose.

This is the general syntax:

```{r if sintax, eval=F, echo=T}
if (condition) {
expr
}
```

--
A simple example:

```{r example if, echo=T}
temp<- -2
if (temp < 0) {
print("It's freezing!")
}
```

---
name: if examples

# Decision, an if-clause

Two examples of using `if` inside of a loop:

Let's display only the numbers that are greater than 5 in the sequence $[1, 10]$
```{r simple if, echo=T}
v <- 1:10
for (i in v) {
if (i > 5) { # if clause
cat(i, ' ')
}
}
```

--

Let's display only odd numbers in the sequence $[1, 10]$:

```{r if, echo=T}
v <- 1:10
Expand All @@ -296,9 +340,13 @@ name:if_else

# Decisions &mdash; if-else

What if we want to perform an action when the first `if` condition is not met?

If we want to print 'o' for an odd number and 'e' for an even, we could write either of:

.pull-left-50[

Only `if` clauses
```{r ifelse1, echo=T}
v <- 1:10
for (i in v) {
Expand All @@ -310,11 +358,13 @@ for (i in v) {
}
}
```

]

--

.pull-right-50[
Using `if-else`:
```{r ifelse2, echo=T}
v <- 1:10
for (i in v) {
Expand All @@ -325,33 +375,19 @@ for (i in v) {
}
}
```
]

--

.pull-left-50[
```{r ifelse3, echo=T}
v <- 1:10
for (i in v) {
tmp <- 'e ' # set default to even
if (i %% 2 != 0) { # if clause
tmp <- 'o ' # change default for odd numbers
}
cat(tmp)
}
```
]

--

Each of these three ways are equally good and are mainly the matter of style...

---
name: elif

# Decision taking &mdash; more alternatives

So far, so good, but we were only dealing with 3 alternatives. Let's say that we want to print '?' for zero, 'e' for even and 'o' for an odd number:
So far, so good, but we were only dealing with 2 alternatives.

Let's say that we want to print '?' for zero, 'e' for even and 'o' for an odd number:

We can use the **if-else-if** clause for this!

```{r if.elseif, echo=T}
v <- c(0:10)
Expand All @@ -365,11 +401,11 @@ for (i in v) {
}
}
```
Congratulations! You have just learned the **if-elseif-else** clause.


---
name: switch

exclude: true
# Switch

If-else clauses operate on logical values. What if we want to take decisions based on non-logical values? Well, if-else will still work by evaluating a number of comparisons, but we can also use **switch**:
Expand All @@ -396,13 +432,25 @@ name: fns

Often, it is really handy to re-use some code we have written or to pack together the code that is doing some task. Functions are a really good way to do this in R:

This is the general syntax

```{r function syntax, eval=F, echo=T}
function_name <- function(arg1, arg2, ...) {
expr
return(something)
}
```

--

Let's see a simple example of a function to add one to a number:

```{r functions1, echo=T,error=T}
add.one <- function(arg1) {
arg1 <- arg1 + 1
return(arg1)
}
add.one(1)
add.one()
```

---
Expand Down Expand Up @@ -451,17 +499,6 @@ args.demo(x=1, 2, 3)
args.demo(arg3=3, x=1, y=2)
```

<!--
--
```{r functions4, echo=F, error=F}
args.demo2 <- function(x, arg2, arg3) {
print(paste('x =', x, 'arg2 =', arg2, 'arg3 =', arg3))
}
#args.demo2(x=1, y=2, ar=3)
```
-->

---
name: variable_scope

Expand All @@ -478,6 +515,7 @@ xyplus <- function(x) {
}
xyplus(x)
x
```
]

Expand Down Expand Up @@ -511,16 +549,16 @@ my.plot <- function(x, y, ...) { # Passing downstream
plot(x, y, las=1, cex.axis=.8, ...)
}
{par(mfrow=c(1,2),mar=c(4,4,1,1))
par(mfrow=c(1,2),mar=c(4,4,1,1))
my.plot(1,1)
my.plot(1, 1, col='red', pch=19)}
my.plot(1, 1, col='red', pch=19)
```

- A function enclosing a function is a **wrapper function**

---
name: ellipsis_trick

exclude:true
# Functions &mdash; the ellipsis argument trick

What if the authors of, e.g. plot.something wrapper forgot about the `...`?
Expand All @@ -534,6 +572,7 @@ my.plot(1, 1, col='red', pch=19)
```

---
exclude:true
<!--
name: lazy_eval
Expand All @@ -559,7 +598,7 @@ name: everything_is_a_fn

Because in R everything is a function

```{r fns.everything_1, echo=F}
```{r fns.everything_1, echo=T}
`+`
```

Expand Down Expand Up @@ -587,7 +626,7 @@ rm("+")

---
name: infix_fns

exclude:true
# Infix notation

Operators like `+`, `-` or `*` are using the so-called **infix** functions, where the function name is between arguments. We can define our own:
Expand Down

0 comments on commit db1e9dc

Please sign in to comment.