Reputation: 11981
lets say I have a tibble which looks like this:
library(tidyverse)
tib <- tibble (a = 1:3, b = 4:6, d = -1:1)
I want to add a column to this tibble where each entry is a function with parameters a,b and d (like f(x) = ax^2 + bx +d). This would mean that (e.g) in the first row I would like to add the function f(x) = 1 x ^2 + 4 x -1, and so on.
I tried the following:
tib2 <- tib %>%
mutate(fun = list(function(x) {a*x^2+b*x+d}))
This does not work since the functions do not know what a, b and d are.
I managed to build a work-around solution using the function mapply
lf <- mapply(function(a,b,d){return(function(x){a*x^2 + b*x + d})}, tib$a, tib$b, tib$d)
tib3 <- tib %>%
add_column(lf)
I was wondering if anyone knows a more elegant way of doing this within the tidyverse. It feels like there is a way using the map function from the purrr package, but I did not manage to get it working.
Thank you
Upvotes: 2
Views: 1088
Reputation: 9107
When you used mutate
in your example, you were giving it a list with one element (function). So this one function was recycled for all the other rows. Also, inside the definition of the function, it doesn't have any visibility of a
, b
or d
.
You can instead use pmap
so that each row has its own function.
tib2 <- tib %>%
mutate(
fun = pmap(
list(a, b, d),
~function(x) ..1 * x^2 + ..2 * x + ..3))
tib2
#> # A tibble: 3 x 4
#> a b d fun
#> <int> <int> <int> <list>
#> 1 1 4 -1 <fun>
#> 2 2 5 0 <fun>
#> 3 3 6 1 <fun>
tib2$fun[[1]](1)
#> [1] 4
Upvotes: 1