Skip to content

Commit 374e042

Browse files
committed
programming section added
1 parent 57d9599 commit 374e042

File tree

2 files changed

+305
-38
lines changed

2 files changed

+305
-38
lines changed

01.Syntax-tutorial-guided.Rmd

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,133 @@ add_2_numbers <- function(a, b) {
22662266
(result_2 <- add_2_numbers(5, 4))
22672267
```
22682268

2269+
### Named parameters
2270+
2271+
Just like with built-ins you can name parameters. You can also use default values.
2272+
2273+
```{r, named-parameters-in-user-defined-functions, exercise=T, exercise.lines=9}
2274+
add_2_vectors <- function(x, y) {
2275+
sum(x, y)
2276+
}
2277+
# now use the function
2278+
set.seed(1234)
2279+
(a <- sample(c(1:100), size = 10, replace = T))
2280+
(b <- c(sample(c(1:100), 4, T), NA, c(sample(c(1:100), 5, T))))
2281+
add_2_vectors(x = a,
2282+
y = b)
2283+
```
2284+
We might want to fix this hiccup by adding a default parameter to indicate that if `NA`s are found they can be safely ignored.
2285+
2286+
```{r, named-parameters-in-user-defined-functions-NAs-addressed-setup}
2287+
set.seed(1234)
2288+
a <- sample(c(1:100), size = 10, replace = T)
2289+
b <- c(sample(c(1:100), 4, T), NA, c(sample(c(1:100), 5, T)))
2290+
```
2291+
2292+
```{r, named-parameters-in-user-defined-functions-NAs-addressed, exercise=T, exercise.lines=4, exercise.setup="named-parameters-in-user-defined-functions-NAs-addressed-setup"}
2293+
add_2_vectors <- function(x, y, remove.na = TRUE) {
2294+
sum(x, y, na.rm = remove.na)
2295+
}
2296+
add_2_vectors(x = a, y = b)
2297+
```
2298+
2299+
Most R functions have parameters to ignore the presence of missing values.
2300+
2301+
## Control of execution
2302+
2303+
For a program or a function to do interesting calculations it is necessary to operate repetitively over data structures like vectors and lists to generate new values or a single one representing the desired target.
2304+
2305+
The line by line flow of execution of an R program can be altered with the use of functions or statements. Both methods are available in R. Using functions leads to a functional style of programming while using statements leads to procedural style.
2306+
2307+
### The procedural statements
2308+
2309+
The procedural style syntax for looping or iterating uses the following structures:
2310+
2311+
```{r, if-statement, eval=FALSE, echo=TRUE, include=TRUE}
2312+
if (condition) {
2313+
Do something
2314+
} else {
2315+
Do something different
2316+
}
2317+
```
2318+
2319+
```{r while-statement, eval=FALSE, echo=TRUE, include=TRUE}
2320+
while (condition) {
2321+
Do something
2322+
}
2323+
```
2324+
2325+
```{r for-statement, eval=FALSE, echo=TRUE, include=TRUE}
2326+
for (variable in sequence) {
2327+
Do something
2328+
}
2329+
```
2330+
2331+
### The functional style
2332+
2333+
The functional forms of these structures can be formulated depending on the object that the user-function is applied to. For a vector the applications are straight forward.
2334+
2335+
The functional and procedural styles of writing programs are equivalent, however for the majority of the applications in statistics and linear algebra R is optimized to use the functional style. More recently packages like `purr` from the `tidyverse` syntax have added all the functional tools that make it extremely succinct to express standard transformations on vectorized data structures like lists, matrices, arrays, and data frames.
2336+
2337+
Let's have a look at concrete examples.
2338+
2339+
### Iterating over a vector
2340+
2341+
2342+
First illustrate the `sapply` function to square all the elements of a numeric vector.
2343+
2344+
```{r, sapply-example-on-vector, exercise=T, exercise.lines=4}
2345+
set.seed(456)
2346+
v <- runif(5, 1, 5)
2347+
# now iterate over the vector applying your operation to square each element
2348+
(squares2 <- sapply(v, function(a) {a*a}))
2349+
```
2350+
2351+
```{r, sapply-vs-for-loop-comparison-setup}
2352+
set.seed(456)
2353+
v <- runif(5, 1, 5)
2354+
```
2355+
2356+
Now use the for-loop to achieve the same transformation.
2357+
2358+
```{r, for-loop-example-on-vector, exercise=T, exercise.lines=9, exercise.setup="r, sapply-vs-for-loop-comparison-setup"}
2359+
# pre-allocate space in the vector
2360+
square_vals <- rep(0, length(v))
2361+
i = 1
2362+
for (a in v) {
2363+
square_vals[i] = a*a
2364+
i = i + 1
2365+
}
2366+
# display the answer
2367+
square_vals
2368+
```
2369+
### Conditionally removing values from a vector
2370+
2371+
In functional style this is done via subsetting. In procedural style a combination of a for-loop and the conditional-statements with if-else can achieve the same result. Let us have a look at the air fare to sun destinations at or below $1200.
2372+
2373+
```{r, conditionally-removing-with-filter, exercise=T, exercise.lines=2}
2374+
air_fares <- c(Habana=1200, Cancun=1150, Los_cabos=960, Costa_Rica=1250)
2375+
(results <- air_fares[air_fares <= 1200])
2376+
```
2377+
Now let's do it in procedural style.
2378+
```{r, conditionally-removing-with-for-loop-and-if-statement-setup}
2379+
air_fares <- c(Habana=1200, Cancun=1150, Los_cabos=960, Costa_Rica=1250)
2380+
```
2381+
2382+
2383+
```{r, conditionally-removing-with-for-loop-and-if-statement, exercise=T, exercise.lines=9, exercise.setup="conditionally-removing-with-for-loop-and-if-statement-setup"}
2384+
results <- c()
2385+
if (length(air_fares) > 0) {
2386+
n <- length(air_fares)
2387+
for (i in 1:n) {
2388+
if (air_fares[i] <= 1200) {
2389+
results <- c(results, air_fares[i])
2390+
}
2391+
}
2392+
}
2393+
results
2394+
```
2395+
22692396

22702397

22712398
## References

0 commit comments

Comments
 (0)