Iterating over the rows of a data.frame with purrr — Part 2
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
A year ago I already wrote an article how to iterate over the rows of a data.frame.
Now I’ve run into another special case. Last year we used pmap_dfr()
to pass
each element of a row as single parameter to our custom function.
But what should you do if your function accepts a data.frame (or list) as one single parameter?
The function …
But let’s look at our example first:
1 2 3 4 5 6 7 8 9 10 11 |
my_function <- function(repeated = 1, text = "a", number_rows = 2) { row <- data.frame( `repeated` = repeated, `text` = text, `number_rows` = number_rows, generated_text = paste(replicate(repeated, text), collapse = "") ) return(do.call("rbind", replicate(number_rows, row, simplify = FALSE))) } my_function(3, "Hello ", 4) |
1 2 3 4 5 |
## repeated text number_rows generated_text ## 1 3 Hello 4 Hello Hello Hello ## 2 3 Hello 4 Hello Hello Hello ## 3 3 Hello 4 Hello Hello Hello ## 4 3 Hello 4 Hello Hello Hello |
Let’s change this function a little bit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
my_new_function <- function(input_data) { row <- data.frame( `repeated` = input_data$repeated, `text` = input_data$text, `number_rows` = input_data$number_rows, generated_text = paste(replicate(input_data$repeated, input_data$text), collapse = "") ) return(do.call("rbind", replicate(input_data$number_rows, row, simplify = FALSE))) } input_data <- data.frame( repeated = 3, text = "Hello ", number_rows = 4 ) my_new_function(input_data) |
1 2 3 4 5 |
## repeated text number_rows generated_text ## 1 3 Hello 4 Hello Hello Hello ## 2 3 Hello 4 Hello Hello Hello ## 3 3 Hello 4 Hello Hello Hello ## 4 3 Hello 4 Hello Hello Hello |
… and its parameters
Now we want to call the function my_new_function
with each row of the
following data.frame as parameter:
1 2 3 4 5 6 7 8 9 10 11 |
options(tidyverse.quiet = TRUE) library(tidyverse, warn.conflicts = FALSE) parameters <- tribble( ~repeated, ~text, ~number_rows, 1, "one", 3, 2, "two", 2, 3, "three", 1 ) %>% as.data.frame() parameters |
1 2 3 4 |
## repeated text number_rows ## 1 1 one 3 ## 2 2 two 2 ## 3 3 three 1 |
Iterating again
Using purrr::pmap_dfr()
won’t work because our function expects one single
argument.
So we use purrr::pmap()
to convert each row into a data.frame and combine
these data.frames to a list. Then we can use purrr::map_dfr()
.
1 2 3 |
parameters %>% purrr::pmap(data.frame) %>% purrr::map_dfr(my_new_function) |
1 2 3 4 5 6 7 |
## repeated text number_rows generated_text ## 1 1 one 3 one ## 2 1 one 3 one ## 3 1 one 3 one ## 4 2 two 2 twotwo ## 5 2 two 2 twotwo ## 6 3 three 1 threethreethree |
Notes
When I had found the above solution for my problem I googled for a solution
with one single purrr
function call. During this search I found this
page
by Jenny Bryan who is very inspiring for all
purrr
related stuff.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.