Exercises

5 Functions

Download the materials for this week’s exercises here.

5.1 Write a function to calculate exponents

Square a number

You’re tired of writing x^2 when you want to square x, so you want a function to square a number. You can call it square(). I showed this in the slides, now try on your own!

# start out with a number to test
x <- 3
# you'll want your function to return this number
x^2
square <- function() {
  
}
# test it out
square(x)
square(53)
53^2 # does this match?

Raise to any power

You don’t just want to square numbers, you want to raise them to higher powers too. Make a function that uses two arguments, x for a number, and power for the power. Call it raise().

raise <- function() {
  
}

# test with
raise(x = 2, power = 4)
# should give you
2^4

Default arguments

Change your raise() function to default to squaring x when the user doesn’t enter a value for power.

# test
raise(x = 5)
# should give you
5^2

5.2 Change the grouping variable when summarizing

Notice that we didn’t need any packages or data to write the functions above. Now we’ll need our usuals, though:

library(tidyverse)
nlsy <- read_csv("nlsy_cc.csv")

Grouping argument

We want to run code like this for multiple variables:

nlsy %>% group_by(sex) %>% 
  summarize(mean_inc = mean(income), .groups = "drop")
#>  # A tibble: 2 x 2
#>      sex mean_inc
#>    <dbl>    <dbl>
#>  1     1   16690.
#>  2     2   14292.
nlsy %>% group_by(glasses) %>% 
  summarize(mean_inc = mean(income), .groups = "drop")
#>  # A tibble: 2 x 2
#>    glasses mean_inc
#>      <dbl>    <dbl>
#>  1       0   13853.
#>  2       1   16626.

Write a function to calculate the stratified mean income for grouping variable var. In other words, write a function such that mean_group_inc(var = "sex") and mean_group_inc(var = "glasses") produce the results above.

Look at the function from the slides for help:

var_q <- function(q, var) {
  quant <- nlsy %>%
    rename(new_var = var) %>% #<<
    summarize(q_var = quantile(new_var, probs = q))
  return(quant)
}
var_q(q = 0.5, var = "income")
#>  Note: Using an external vector in selections is ambiguous.
#>  ℹ Use `all_of(var)` instead of `var` to silence this message.
#>  ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#>  This message is displayed once per session.
#>  # A tibble: 1 x 1
#>    q_var
#>    <dbl>
#>  1 11155

Write your function here:

mean_group_inc <- function(var) {
  
}

# test with
mean_group_inc(var = "glasses")
#>  NULL
mean_group_inc(var = "sex")
#>  NULL

Grouping and summarizing arguments

Rewrite your function to accept two arguments: group_var to determine what the grouping variable is, and mean_var to determine what variable you want to take the mean of (e.g., mean_group(group_var = "sex", mean_var = "income") should give you the same results as above).

mean_group <- function(group_var, mean_var) {
  
}

# test with
mean_group(group_var = "sex", mean_var = "income")
#>  NULL

5.3 For loops

Write a for loop

We used this function:

var_q_new <- function(q, var) {
  quant <- nlsy %>%
    rename(new_var = var) %>%
    summarize(q_var = quantile(new_var, probs = q)) %>%
    pull(q_var)
  return(quant)
}
var_q_new(q = 0.5, var = "income")
#>    50% 
#>  11155

inside of a for loop in order to calculate each decile of income:

qs <- seq(0.1, 0.9, by = 0.1)
deciles <- rep(NA, length(qs))
for (i in seq_along(qs)) {
  deciles[[i]] <- var_q_new(q = qs[[i]], 
                        var = "income")
}
deciles
#>  [1]  3177.2  5025.6  6907.2  9000.0 11155.0 14000.0 18053.6 23800.0 33024.0

Try changing seq_along(qs) to 1:5 and run the whole chunk again. What does deciles print now?

Change the for loop above to loop over different variables instead of different quantiles. That is, calculate the 0.25 quantile for each of c("income", "age_bir", "nsibs") in a for loop.

vars <- c("income", "age_bir", "nsibs")
q_25s <- ...

Nested loops

You can nest for loops inside each other, as long as you use different iteration variables. Write a nested for loop to iterate over variables (with i) and quantiles (with j). You’ll need to start with an empty matrix instead of a vector, with rows indexed by i and columns by j. Calculate each of the deciles for each of the above variables.

vars <- ...
qs <- ...
results_mat <- matrix(NA, ncol = ..., nrow = ...)