<- 3:12 nums
PA 9: Writing Functions
You will write several small functions, then use them to unscramble a message. Many of the functions have been started for you below, but none of them are complete as is.
This task is complex. It requires many different types of abilities. Everyone will be good at some of these abilities but nobody will be good at all of them. In order to produce the best product possible, you will need to use the skills of each member of your group.
1. Write code to manipulate the vector of numbers nums
. Your code should divide each element in the vector by the smallest element and round the results to the nearest whole number. Hint: This code should not be a function. Consider using the existing functions round()
and min()
and don’t forget to account for NA
values.
2. Turn your code from Q1 into a function called divide_and_round()
. Fill in the skeleton code below.
<- function(vec){
divide_and_round
}
3. Test your function by running the code below.
<- c(5:10, NA)
test divide_and_round(test) #you should see mostly values of 1 and 2, plus an NA
NULL
4. Write code to manipulate the vector of numbers nums
. Your code should, for each element, return TRUE
if the number is NOT divisible by 9 OR 12, and return FALSE
otherwise. Hint: This code should not be a function. Note - the function %%
is handy here - look it up if you do not know what it does.
ifelse(nums %% 9 == 0 ___ nums %% 12 == 0, ____ , ____) #it should say FALSE for 9 and 12 positions
Error in parse(text = input): <text>:1:23: unexpected input
1: ifelse(nums %% 9 == 0 _
^
5. Turn your code from Q4 into a function called no_nines_or_twelves()
.
<- function(vec) {
no_nines_or_twelves
}
6. Test your function by running the code below.
<- c(seq(from = 15, to = 60, by = 5), NA)
test test
[1] 15 20 25 30 35 40 45 50 55 60 NA
no_nines_or_twelves(test) #45 and 60 should have FALSE in their positions and NA in the last
NULL
7. Write a function called every_other()
. This function should take in a vector and return every other value in the vector. Include an optional argument called start
which lets you choose where to start skipping; that is, if start = 1
, the function returns the 1st, 3rd, 5th, etc. values and if start = 2
, the function returns the 2nd, 4th, 6th, etc. values.
Hint: Do not use a for()
loop to do this! Accomplish this with the seq_along()
function, bracket subsetting ([]
), and modulus arithmetic (%%
).
# the following identify if a value is even or odd
seq_along(nums)) %% 2 == 0 (
[1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
seq_along(nums)) %% 2 > 0 (
[1] TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE
# using [] to subset will keep values with TRUE in that element's position
seq_along(nums)) %% 2 == 0] #should return even numbers nums[(
[1] 4 6 8 10 12
seq_along(nums)) %% 2 > 0] #should return odd numbers nums[(
[1] 3 5 7 9 11
Fill in the skeleton below. Remember the default should be start
as 1.
<- function(vec, _________){
every_other
if (start == 2) {
vec[]
}
else if (start == 1) {
vec[]
}
}
Error in parse(text = input): <text>:1:30: unexpected input
1: every_other <- function(vec, _
^
8. Test your function by running the code below.
<- c(1:10)
test
every_other(test, start = 1) #return odds
Error in every_other(test, start = 1): could not find function "every_other"
every_other(test, start = 2) #return evens
Error in every_other(test, start = 2): could not find function "every_other"
9. Write a function called shorten()
. This function should take in a vector, drop all values BEFORE the cumulative sum is greater than a provided number, and return the remaining values from the original vector.
Hint: Do not use a while()
loop to do this! Accomplish this with the cumsum()
function and bracketing.
Here is an example of testing if the cumulative sum is greater than or equal to 30.
# look at the following - which completes the task needed
cumsum(nums)
[1] 3 7 12 18 25 33 42 52 63 75
cumsum(nums) >= 30
[1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
cumsum(nums) >= 30] #returns only numbers 8+ nums[
[1] 8 9 10 11 12
<- function(x, sum){
shorten
}
10. Test your function by running the code below.
<- 20:50
test shorten(test, 350) #should be 33+
NULL
11. Once you have written your four functions correctly, run the following code:
#remember to use the green arrow to run the whole code chunk
<- c(39, 1.87, 48, 11, 8, 45, 21, 5, 12, 33, 9, 11, 108,
my_vec 4, 18, 5, 16, 17, 8, 48, 27, 24, 4, 22, 12, 27, 23,
46, 42, 35, 15, 34, 36, 26, 18, 10, 18.21, 72.04,
36.9, 41.81, 29, 89.75, 34.03, 20.18, 48.74, 15.76,
31.86, 83.6, 43.55, 39.99, 23.55, 8.54, 24.71, 22.02,
9.71, 62.14, 35.46, 16.61, 15.66, 21.29, 30.52,
201.07, 45.81, 7.85, 30.13, 34.14, 22.62, 10.2, 6.02,
30.12, 10.64, 31.72, 24.57, 14.43, 43.37, 89.93,
44.72, 51.32, 13.62, 45.56, 22.96, 7.05, 29.99, 41.38,
26.59, 23.04, 19.82, 50.73, 39.56, 43.79, 30.22, 85.85,
5.78, 78.85, 29.52, 66.27, 44.06, 27.28, 24.43, 64.32,
3.35, 67.45, 46.72, 48.44, 48.65, 33.3, 40.28, 19.04)
<- every_other(my_vec, start = 2) my_vec
Error in every_other(my_vec, start = 2): could not find function "every_other"
# Should have 54 elements!
<- divide_and_round(my_vec)
my_vec
<- every_other(my_vec, start = 1) my_vec
Error in every_other(my_vec, start = 1): could not find function "every_other"
# Should have 27 elements!
<- shorten(my_vec, 350)
my_vec # Should have 12 elements!
<- my_vec[no_nines_or_twelves(my_vec)]
my_vec # Should have 6 elements!
<- sort(my_vec)
my_vec
my_vec
NULL
Canvas Submission
If you have done everything correctly, your final vector will be six numbers long. Google these six numbers to find a TV show they are famously associated with as your final answer and submit to Canvas.