## Workflow

How should you turn your code into functions? Always follow these four steps:

- Create a real R object (or set of objects) to use with your function
- Write code that works with the real object(s)
- Wrap the code in
`function()`

- Assign the names of your real objects as argument names to the function

These steps are the best practice for writing functions in R. When you follow these steps, your functions are guaranteed to work for at least one case, which means you will spend more time using your functions and less time debugging them.

Let’s use the steps to create your first function.

### Goal - Grading

To make this real, put yourself in the shoes of a teacher:

You’ve given your students 10 homework assignments and announced that you will drop their lowest homework score. Their final grade will be the average score of the remaining homework.

To make your life easier, you want to write an R function that will take a vector of 10 homework scores and return a final grade.

Ready to begin?

Remember our steps:

- Create a real R object (or set of objects) to use with your function

- Create an object named
`x`

that contains the vector `c(100, 100, 100, 100, 100, 100, 100, 100, 100, 90)`

(hint: use copy and paste!). Then click Submit Answer. `x`

will be the grades of your test student.

`x <- c(100, 100, 100, 100, 100, 100, 100, 100, 100, 90)`

`strict_check("Now you can use x to develop and test your code")`

- Write code that works with the real object(s)

Recall the grading scheme: the final grade is the average homework score after you drop the lowest score. Since there are many ways to calculate this, let’s be specific and end up on the same page.

- Use
`sum()`

, `min()`

, `/`

, `9`

and parentheses to calculate the final grade for student `x`

. Click Submit Answer to check that your code works.

`x`

`"Your code should return 100."`

`(sum(x) - min(x)) / 9`

`strict_check("This is the crucial step in writing a function. It is important to get your code working in real life with a real object before you try to abstract the code into a reusable function.")`

- Wrap the code in
`function()`

The `function()`

function builds a function from a piece of R code. To use it, call `function()`

followed by an opening brace, `{`

. Then write one or more lines of R code followed by a closed brace, `}`

, e.g.

```
foo <- function() {
a <- 1
b <- 2
a + b
}
```

`function()`

will return a function that uses everything between the braces as its code body. If you’d like to save the function, you’ll need to assign it in the usual way to an R object that you can call later.

As you write your functions, recall that R will only return the result of the last line in the code body when you call the function (we’ll learn about some exceptions to this rule in the Control Flow tutorial).

Once you save a function, you can run it and inspect its contents.

`foo()`

`## [1] 3`

`foo`

```
## function() {
## a <- 1
## b <- 2
## a + b
## }
```

### Your turn

Let’s save your code as a function.

- Save the code below as a function named
`grade`

. Then click Submit Answer.

`(sum(x) - min(x)) / 9`

`"Use the function() {} function."`

```
grade <- function() {
(sum(x) - min(x)) / 9
}
```

`strict_check("Now that you've saved grade as a function, you can call it whenever you like, but there is still one more thing to do...")`

At the moment, your `grade()`

function is reusable but not *generalizable*. Each time you call `grade()`

it computes the final grade of the vector `x`

that contains `c(100, 100, 100, 100, 100, 100, 100, 100, 100, 90)`

.

`grade()`

`## [1] 100`

`grade()`

`## [1] 100`

We’d like to use `grade()`

with new vectors that have new values.

### Arguments

- Assign the names of your real objects as argument names to the function

You can make a function generalizable by turning some of the objects in its code body into *formal arguments*. A formal argument is an object that a user can assign a value to when he or she calls the function. The function will use the user’s value for the object when it executes its code body.

For example, we’d like to tell R that `x`

in `grade()`

is an argument. R shouldn’t use a pre-defined value for `x`

; it should let the user supply a new value for `x`

each time he or she runs the function.

```
grade <- function() {
(sum(x) - min(x)) / 9
}
```

How do you tell R that an object is a formal argument?

You list the name of the object in the parentheses that follow `function()`

in the function definition. If you make more than one argument, separate their names with a comma. For example, you could make `a`

and `b`

arguments of my `foo`

function.

```
foo <- function(a, b) {
a + b
}
```

Now I can define a new value for `a`

and `b`

each time I call `foo`

.

`foo(a = 1, b = 1)`

`## [1] 2`

`foo(a = 100, b = 200)`

`## [1] 300`

### Default values

To give an argument a default value, set it equal to a value when you define the function. For example, the code below will set the default value of `b`

in `foo`

to one.

```
foo <- function(a, b = 1) {
a + b
}
foo(a = 2)
```

`## [1] 3`

`foo(a = 2, b = 2)`

`## [1] 4`

Interesting, huh? Now apply what you’ve learned to `grade()`

.

- Change the code below to list
`x`

as a formal argument of `grade()`

. Then click Submit Answer.

```
grade <- function() {
(sum(x) - min(x)) / 9
}
```

```
grade <- function(x) {
(sum(x) - min(x)) / 9
}
```

`strict_check('If you use the "best practice" workflow, your argument names will always be the names of the real R objects that you create in Step 1. Nice and simple.')`

Good job! You can now have a finished `grade()`

function that you can use to calculate the final grade of *any* vector (I mean, student). Try it out.

- Calculate the final grade of the vector
`c(100, 90, 90, 90, 90, 90, 90, 90, 90, 80)`

. Then click Submit Answer.

```
grade <- function(x) {
(sum(x) - min(x)) / 9
}
```

`grade(x = c(100, 90, 90, 90, 90, 90, 90, 90, 90, 80))`

`strict_check("Let's recap the function writing workflow.")`

### Quiz

### Recap

Use the four step workflow whenever you need to write a function:

- Create a real R object (or set of objects) to use with your function
- Write code that works with the real object(s)
- Wrap the code in
`function()`

- Assign the names of your real objects as argument names to the function

## Function look-alikes

As an R user, you may have already made things that resemble functions.

Here are two examples that may be familiar. In each case, you can easily convert your code into a function.

### Functions and pipes

It is also easy to use pipes like simple functions because you can copy and paste a pipe behind different objects. For example, this pipe would compute sum of squares of any vector that you place it behind.

```
c(1, 1, 1) %>%
sqrt() %>%
sum()
```

`## [1] 3`

```
c(1, 2, 3, 4, 5) %>%
sqrt() %>%
sum()
```

`## [1] 8.382332`

It is a good idea to turn a pipe into a function when you find yourself using it often. You don’t need to rewrite the pipe to do this. Pipes come with a handy shortcut for turning them into functions.

To turn a pipe into a function, replace its initial object with a `.`

, and then save the pipe to an object. R will treat the object as a function that passes its argument to the beginning of the pipe.

```
l2_pipe <- . %>%
sqrt() %>%
sum()
l2_pipe(c(1, 1, 1))
```

`## [1] 3`

## Practice

Congratulations on finishing the tutorial. Before you go, complete the following exercises to cement your skills!

### Exercise 1

### Exercise 2

What will the following code return?

```
f <- function(a, b, c) {
a
b
c
}
f(1, 2, 3)
```

### Exercise 3

Let’s write a function that grades by counting a student’s highest score twice and then taking an average of the 11 scores.

### Exercise 4

- Write a piece of code that uses
`max()`

to double count the highest score in `x`

and then takes the average of the 11 results. Click Submit Answer to check that your code works.

`x`

`"Your code should retrun the answer 99.09091."`

`(sum(x) + max(x)) / 11`

`strict_check("That student will be pleased!")`

### Exercise 5

- Wrap your code in
`function()`

and save it to the name `grade2`

. - Then define the argument(s) for the function.
- Then click Submit Answer.

`(sum(x) + max(x)) / 11`

`"When you use this workflow, the names of the argument(s) are always the names of the object(s) that you created in step 1."`

```
grade2 <- function(x) {
(sum(x) + max(x)) / 11
}
```

`strict_check("Your skills are almost complete.")`

### Exercise 6

It’s time to put it all together.

- Use the code block below to develop a function named
`l2`

that calculates the Euclidean distance, or L_{2} norm (\(\|x||_{2}\)), of a vector of numbers named `x`

. The L_{2} norm is the square root of the sum of the squared values in the vector, i.e.

\[\| x \|_{2} = \sqrt{\sum_{i = 1}^{n} x_{i}^{2}}\]

- When you are finished, reduce your code to just the definition of your function. Then click Submit Answer.

`"You've already seen the code for the l2 function earlier in this tutorial (I do not mean the pipe example)."`

`"Consider using sqrt(), sum(), and ^2. Your code will work with vectors of any length."`

```
l2 <- function(x) {
sqrt(sum(x^2))
}
```

`strict_check("You have correctly implemented the euclidean distance function.")`