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.