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

≡放荡痞女 提交于 2020-01-24 15:41:10

问题


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.


回答1:


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
...



回答2:


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)



回答3:


You could use Vectorize

input <- expand.grid(species_vecs,sepal_thres_vecs,stringsAsFactors = F) %>% rename(species=Var1, sepal_thres=Var2)
#     species sepal_thres
# 1 virginica           5
# 2    setosa           5
# 3 virginica           6
# 4    setosa           6
output <- Vectorize(myfunc,c("species","sepal_thres"),SIMPLIFY=F)(dat=iris,species=input[[1]],sepal_thres=input[[2]])
output[[1]]
#   Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
# 1          4.9         2.5          4.5         1.7 virginica
output[[3]]
# Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
# 1          5.8         2.7          5.1         1.9 virginica
# 2          4.9         2.5          4.5         1.7 virginica
# 3          5.7         2.5          5.0         2.0 virginica
# 4          5.8         2.8          5.1         2.4 virginica
# 5          6.0         2.2          5.0         1.5 virginica
# 6          5.6         2.8          4.9         2.0 virginica
# 7          6.0         3.0          4.8         1.8 virginica
# 8          5.8         2.7          5.1         1.9 virginica
# 9          5.9         3.0          5.1         1.8 virginica


来源:https://stackoverflow.com/questions/46902461/how-to-pass-a-dataframe-and-uneven-vectors-as-parameters-in-purrr-map

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!