Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a dataframe and uneven vectors as parameters in purrr map

Tags:

r

dplyr

purrr

I have a function with mixed data types. It takes a data frame and string variable as the input parameter.


library(dplyr)


myfunc <- function (dat=NULL,species=NULL,sepal_thres=NULL) {
 dat %>% 
    filter(Species==species & Sepal.Length <= sepal_thres) 

}

myfunc(dat=iris,species="virginica",sepal_thres=5)
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
#> 1          4.9         2.5          4.5         1.7 virginica

But I want to apply it with list of vectors

species_vecs <- c("virginica","setosa")
sepal_thres_vecs <- c(5, 6)
purrr::pmap(list(dat=iris, species=species_vecs, sepal_thres=sepal_thres_vecs), myfunc)

I got this error:

Error: Element 2 has length 2, not 1 or 5.

What's the right way to do it?

Not that the species and sepal_tres parameters are taken from this combination:

 > expand.grid(species_vecs,sepal_thres_vecs) %>% rename(species=Var1, sepal_thres=Var2)
    species sepal_thres
1 virginica           5
2    setosa           5
3 virginica           6
4    setosa           6

but dat as parameter is fixed.

like image 511
scamander Avatar asked Oct 28 '25 08:10

scamander


2 Answers

pmap will use recycling if you have a length-1 element as part of your bigger list. In this case, you can pass iris as a list element within the full list to use it for each species-sepal combination.

Note that pmap goes through list elements with multiple values in the order they appear. If you want every combination of the species and sepal vectors in pmap you would need to create and give the full vectors as list elements (i.e., you would have to do the crossing yourself).

purrr::pmap(list(dat = list(iris), species = rep(species_vecs, 2), 
                 sepal_thres = rep(sepal_thres_vecs, each = 2) ), myfunc)

[[1]]
  Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
1          4.9         2.5          4.5         1.7 virginica

[[2]]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           4.9         3.0          1.4         0.2  setosa
2           4.7         3.2          1.3         0.2  setosa
3           4.6         3.1          1.5         0.2  setosa
4           5.0         3.6          1.4         0.2  setosa
5           4.6         3.4          1.4         0.3  setosa
6           5.0         3.4          1.5         0.2  setosa
...
like image 113
aosmith Avatar answered Oct 29 '25 23:10

aosmith


You can use this solution :

expand.grid(species_vecs,sepal_thres_vecs) %>% 
  rename(species=Var1, sepal_thres=Var2) %>% 
  as.tibble() %>% 
  mutate(sum = map2(as.character(species), sepal_thres,myfunc,dat = iris)) %>% 
  unnest(sum)
like image 22
Alex Avatar answered Oct 29 '25 22:10

Alex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!