# Functions, Defaults, Dots and Pipes — R Programming

Source: https://www.geekswithgeeks.com/en/r-programming/p-functions

> Write functions with defaults and ..., and chain operations with the pipe.

## Reusable building blocks

Define functions with `function(args) { body }`; the **last evaluated expression** is returned automatically (use `return()` for early exits). Arguments can have **defaults** and can be matched **by name**, so calls such as `round(x, digits = 1)` are clear. The special argument **`...`** (dots) passes extra arguments through to other functions, as in wrappers around `mean()` or `ggplot()`. R uses **lazy evaluation**: arguments are evaluated only when used. Since R 4.1, **anonymous functions** have a short form, `\(x) x * 2`, and the **native pipe** **`|>`** passes the left-hand value as the first argument of the next call, turning nested calls into readable steps (`data |> filter(...) |> summarise(...)`). The magrittr pipe `%>%` from the tidyverse predates it and works similarly, with a few extra features. Functions are objects: you can store them in lists and pass them to other functions. Validate inputs early with `stopifnot()` or `stop("message")`, and signal problems with `warning()` and `message()`.

## A validated function and a pipeline

Defaults, dots, input checks and the native pipe.

```r
gst_total <- function(amount, rate = 0.18, digits = 2) {
  stopifnot(is.numeric(amount), all(amount >= 0, na.rm = TRUE))
  round(amount * (1 + rate), digits)
}

gst_total(c(100, 250))                  # 118.0 295.0
gst_total(100, rate = 0.05)             # named argument

safe_mean <- function(x, ...) {
  if (length(x) == 0) return(NA_real_)  # early return
  mean(x, ...)                          # pass extra arguments such as na.rm
}
safe_mean(c(1, NA, 3), na.rm = TRUE)    # 2

square <- \(x) x^2                       # short anonymous function (R 4.1+)

c(4, 9, 16) |>
  sqrt() |>
  sum() |>
  square()                              # (2 + 3 + 4)^2 = 81
```

## An assembly line

Nested calls like `square(sum(sqrt(x)))` must be read inside out. A pipe is an assembly line: the data moves left to right through each station in the order the work happens.

**Quiz:** What does the native pipe `x |> f(y)` mean?

- [ ] f(y, x)
- [ ] x(f, y)
- [ ] It assigns f to x
- [x] f(x, y)

*Answer:* f(x, y). The pipe inserts the left-hand value as the first argument of the right-hand call.
