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")
#> # 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 = ...)