Take the following vector:
x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Write a function that takes x as an argument and computes the sum of the elements in the vector using a for
loop. Test it against the sum()
function.
sum_for <- function(x) {
sum <- 0
for (i in 1:length(x)) {
sum <- sum + x[i]
}
return(sum)
}
sum_for(x)
## [1] 55
sum(x)
## [1] 55
We now turn towards a relatively easy problem that is often asked as a warm-up in coding interviews.
Write a function that takes an integer number as an argument and puts out the word “fizz” or “buzz” up to that integer. If an integer is divisible by 3, the function should put out “fizz”. If it is divisible by 5, the function should put out “buzz”. If it is divisible by both 3 and 5, the function should put out “fizzbuzz”. If none of the above holds true, the function should simply return the integer as a string.
In a first step, do this using a for
loop and if
statements. If you do not provide an integer number, the function should throw a meaningfull error message.
Tip: remember the modulo operator!
fizzbuzz <- function(int = NULL) {
if (is.numeric(int) == FALSE) {
stop("Please provide an integer number.")
}
else if (int %% 1 != 0) {
stop("Please provide an integer number.")
}
else {
output <- vector(mode = "integer", length(1:int))
for (i in 1:int) {
if (i %% 3 == 0 && i %% 5 == 0) {
output[i] <- "fizzbuzz"
}
else if (i %% 3 == 0) {
output[i] <- "fizz"
}
else if (i %% 5 == 0) {
output[i] <- "buzz"
}
else {
output[i] <- i
}
}
return(output)
}
}
fizzbuzz(50)
## [1] "1" "2" "fizz" "4" "buzz" "fizz"
## [7] "7" "8" "fizz" "buzz" "11" "fizz"
## [13] "13" "14" "fizzbuzz" "16" "17" "fizz"
## [19] "19" "buzz" "fizz" "22" "23" "fizz"
## [25] "buzz" "26" "fizz" "28" "29" "fizzbuzz"
## [31] "31" "32" "fizz" "34" "buzz" "fizz"
## [37] "37" "38" "fizz" "buzz" "41" "fizz"
## [43] "43" "44" "fizzbuzz" "46" "47" "fizz"
## [49] "49" "buzz"
fizzbuzz("3")
## Error in fizzbuzz("3"): Please provide an integer number.
fizzbuzz(3.3)
## Error in fizzbuzz(3.3): Please provide an integer number.
fizzbuzz(TRUE)
## Error in fizzbuzz(TRUE): Please provide an integer number.
Use map()
from the purrr
package to apply the class()
and typeof()
function to each column of the palmerpenguins package.
penguins %>% map(typeof)
## $species
## [1] "integer"
##
## $island
## [1] "integer"
##
## $bill_length_mm
## [1] "double"
##
## $bill_depth_mm
## [1] "double"
##
## $flipper_length_mm
## [1] "integer"
##
## $body_mass_g
## [1] "integer"
##
## $sex
## [1] "integer"
##
## $year
## [1] "integer"
penguins %>% map_chr(typeof)
## species island bill_length_mm bill_depth_mm
## "integer" "integer" "double" "double"
## flipper_length_mm body_mass_g sex year
## "integer" "integer" "integer" "integer"
penguins %>% map_chr(class)
## species island bill_length_mm bill_depth_mm
## "factor" "factor" "numeric" "numeric"
## flipper_length_mm body_mass_g sex year
## "integer" "integer" "factor" "integer"
ADVANCED TASK (skip if you are stuck):
Use map_df
to compute a data frame consisting of variables showing the class and type of each column of the penguins data and a variable storing the column names of the penguins data.
Tip: You need to use data.frame()
inside map_df()
and create the variable you want inside this data.frame()
call. Further, look into the .id
argument of map to get the column names of the penguin data set.
# Compare
penguins %>% map(~ data.frame(
type = typeof(.x),
class = class(.x)
),
.id = "variable"
)
## $species
## type class
## 1 integer factor
##
## $island
## type class
## 1 integer factor
##
## $bill_length_mm
## type class
## 1 double numeric
##
## $bill_depth_mm
## type class
## 1 double numeric
##
## $flipper_length_mm
## type class
## 1 integer integer
##
## $body_mass_g
## type class
## 1 integer integer
##
## $sex
## type class
## 1 integer factor
##
## $year
## type class
## 1 integer integer
# to
penguins %>% map_df(~ data.frame(
type = typeof(.x),
class = class(.x)
),
.id = "variable"
)
## variable type class
## 1 species integer factor
## 2 island integer factor
## 3 bill_length_mm double numeric
## 4 bill_depth_mm double numeric
## 5 flipper_length_mm integer integer
## 6 body_mass_g integer integer
## 7 sex integer factor
## 8 year integer integer
Take the function you defined in Task 2 and rewrite it such that it takes a vector of integers instead and works with purrr::map_chr()
.
fizzbuzz <- function(int = NULL) {
if (is.numeric(int) == FALSE) {
stop("Please provide an integer number.")
}
else if (int %% 1 != 0) {
stop("Please provide an integer number.")
}
else {
if (int %% 3 == 0 && int %% 5 == 0) {
"fizzbuzz"
}
else if (int %% 3 == 0) {
"fizz"
}
else if (int %% 5 == 0) {
"buzz"
}
else {
int
}
}
}
purrr::map_chr(1:50, fizzbuzz)
## [1] "1" "2" "fizz" "4" "buzz" "fizz"
## [7] "7" "8" "fizz" "buzz" "11" "fizz"
## [13] "13" "14" "fizzbuzz" "16" "17" "fizz"
## [19] "19" "buzz" "fizz" "22" "23" "fizz"
## [25] "buzz" "26" "fizz" "28" "29" "fizzbuzz"
## [31] "31" "32" "fizz" "34" "buzz" "fizz"
## [37] "37" "38" "fizz" "buzz" "41" "fizz"
## [43] "43" "44" "fizzbuzz" "46" "47" "fizz"
## [49] "49" "buzz"