---
title: "functions"
subtitle: "Chapter 25"
theme: flatly 
date: today
toc: true
format:
  html: 
    code-overflow: wrap
    toc: true
    toc-title: "Contents"
    # hide code?

execute:
  warning: false
  message: false
---

## Exercise

1. Write a function that takes three parameters (.data, columns, fn) that applies the mathematical function `fn` to the columns of `.data` indexed numerically by `columns`.

```{r sum_fun1, echo = FALSE}
library(tidyverse)
f <- function(.data, columns, fn) {
  .data |> summarize(across({{columns}}, {{ fn }} ))
} 
```

2. Apply your function to two different datasets.

3. Now make a summary function that allows for the possibility to remove `NA`. 
```{r rem_na, echo = FALSE}
f <- function(.data, columns, fn, na_choice = FALSE) {
   if (na_choice){
  clean_data <- select({{.data}},{{columns}}) |> drop_na()
    clean_data |> 
      summarize(across(everything(), {{ fn }} ))
  }
  else 
  .data |> summarize(across({{columns}}, {{ fn }} ))
}
```

4. Perform a simple mathematical operation (e.g., add 1) to a chosen set of columns of a given dataset. (Use across with mutate)

```{r accross, echo = FALSE, eval = FALSE}
mutate(diamonds,across(c(1,5),function(x) x^2))
```


5. Improve your function above to allow users to input the names of the variables.

```{r, echo = FALSE}
f <- function(.data, columns, fn, na_choice) {

  my_data <- select({{.data}},{{ columns }})
    
  if (nargs() > 3) {
    if (na_choice != 0){
    my_data <- my_data |> drop_na()
  }}
    my_data |> summarize(across(everything(), {{ fn }} ))
  }
```

6. Apply a user-defined (non-summary) function to a set of columns of data.

```{r, echo = FALSE}
my_fun <- function(.data, columns, fn, na_choice = FALSE) {

  my_data <- select({{.data}},{{ columns }})
    
    if (na_choice){
    my_data <- my_data |> drop_na()
  }
    my_data |> mutate(across(everything(), {{ fn }} ))
  }
```

7. Recall simple rescaling function from last week
```{r}
rescale <- function(a) {
    rng <- range(a, na.rm = TRUE)
    (a - rng[1])/(rng[2] - rng[1])
}
```

8. Apply it to `rescale` all numeric columns of a dataset.  First do it with a mutate, then write a function that takes `rescale` as a parameter.
```{r, eval=FALSE}
my_fun(diamonds,where(is.numeric),rescale)
```

9. For dynamically naming column names see:

<https://stackoverflow.com/questions/26003574/use-dynamic-name-for-new-column-variable-in-dplyr?rq=1>

![glue](glue_names.png)