Reputation: 53
Here is my problem: I have a function that take 1 double and return several doubles and I would like to directly get them on different columns of the tibble. I tried several methods with mutate()
and/or map()
.
I do not want to call the method n times and take each time a different element of the list returned by the function.
Here is a generic problem of what I am trying to do:
library(tidyverse)
## a random function that return more than 1 element
f <- function(x){
return(list(x/2,x**2))
}
## a tibble with a column on which I apply the function
tib <- tibble( x = rep(100:120))
tib%>%
mutate(y = f(x))
## error:
#Error : Problem with `mutate()` input `y`.
#x Input `y` can't be recycled to size 21.
#ℹ Input `y` is `f(x)`.
#ℹ Input `y` must be size 21 or 1, not 2.
## what I want to avoid:
tib %>%
mutate(y = f(x)[[1]], z = f(x)[[2]])
I have been struggling with this issue for some times now. Apologies if it has been answered already I searched an answer on several forums but got nothing.
Thank you in advance !
Upvotes: 1
Views: 55
Reputation: 3417
You can solve this using nested data frames (or list columns depending on your preferred terminology).
The code below is a generic example of how to do this using mutate and map, which will create the nested data frame, and then unnest:
f <- function(x){
tibble(y = x* 2, z = x*3)
}
tib <- tibble(x = rep(100:120)) %>%
mutate(data = map(x, f)) %>%
unnest()
tib
Upvotes: 2