R语言 将map与自定义函数(返回数据框)和多个输入一起使用

idfiyjo8  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(127)

我有一个非常简单的函数,它返回一个 Dataframe 。该函数接受三个参数,一个数据集和 Dataframe 中的两个变量。
我希望使用map/pmap函数家族来提供输入向量/列表并生成单个(长)输出数据集。我似乎无法使用map/pmap工具。下一步我可以尝试什么?
这个函数非常基本:

library(dplyr)

# Function takes dataset and 2 categorical variables 
# Calculates number of records for each combination of values in the two variables
# Calculates % of var 1 responses for each level of var2
ugh<-function(data, var1, var2){
# add checks to make sure vars on dataset

  tab_n<-data%>%
    group_by_at(c(var1, var2))%>%
    summarise(Numerator=n(), .groups="drop")%>%
    group_by_at(c(var2))%>%
    mutate(Denominator=sum(Numerator)
           ,Pct=Numerator/Denominator*100
# storing names of var1 and var2 for future subsetting
           , Var1=var1 
           , Var2=var2)%>% 
    rename(Var1_levels=var1
           , Var2_levels=var2
           )
}

# Sample output 
combo1<-mtcars%>%ugh(var1="cyl", var2="gear")
# can also run this as: 
# combo1<-ugh(data=mtcars, var1="cyl", var2="gear")
combo2<-mtcars%>%ugh(var1="cyl", var2="carb")
sampleOutput<-rbind(combo1, combo2)

# Trying to use map to generate sampleOutput
var1_vector=rep("cyl", 2) 
var2_vector=c("gear", "carb")

plswork<-mtcars%>%
  map2_dfr(var1=var1_vector, var2=var2_vector, ugh)

我得到的错误消息是:
as_mapper(.f,...)中的错误:缺少参数“.f”,没有默认值
我试过使用~来指定函数,我试过分别使用map 2和绑定行,也试过使用pmap和一个输入列表......但我没有太多的运气。
(我也对更有效的方法感兴趣,通过不同的列子集来总结数据框中的列子集。

vyswwuz2

vyswwuz21#

这个问题有几个解决方案。我推荐第一个,因为我认为它是最清楚的。我还调整了你的函数,以修复任何使用过时/取代的函数/行为。

library(dplyr)
library(purrr)

# Function takes dataset and 2 categorical variables 
# Calculates number of records for each combination of values in the two variables
# Calculates % of var 1 responses for each level of var2
ugh<-function(data, var1, var2){
  # add checks to make sure vars on dataset
  
  tab_n<-data%>%
    group_by(across(all_of(c(var1, var2))))%>%
    summarise(Numerator=n(), .groups="drop")%>%
    group_by(across(all_of(var2)))%>%
    mutate(Denominator=sum(Numerator)
           ,Pct=Numerator/Denominator*100
           # storing names of var1 and var2 for future subsetting
           , Var1= .env$var1 
           , Var2= .env$var2)%>% 
    rename(Var1_levels= all_of(var1)
           , Var2_levels= all_of(var2)
    )
}

# Sample output 
combo1<-mtcars%>%ugh(var1="cyl", var2="gear")
# can also run this as: 
# combo1<-ugh(data=mtcars, var1="cyl", var2="gear")
combo2<-mtcars%>%ugh(var1="cyl", var2="carb")

sampleOutput<-rbind(combo1, combo2)

sampleOutput
#> # A tibble: 17 × 7
#> # Groups:   Var2_levels [7]
#>    Var1_levels Var2_levels Numerator Denominator    Pct Var1  Var2 
#>          <dbl>       <dbl>     <int>       <int>  <dbl> <chr> <chr>
#>  1           4           3         1          15   6.67 cyl   gear 
#>  2           4           4         8          12  66.7  cyl   gear 
#>  3           4           5         2           5  40    cyl   gear 
#>  4           6           3         2          15  13.3  cyl   gear 
#>  5           6           4         4          12  33.3  cyl   gear 
#>  6           6           5         1           5  20    cyl   gear 
#>  7           8           3        12          15  80    cyl   gear 
#>  8           8           5         2           5  40    cyl   gear 
#>  9           4           1         5           7  71.4  cyl   carb 
#> 10           4           2         6          10  60    cyl   carb 
#> 11           6           1         2           7  28.6  cyl   carb 
#> 12           6           4         4          10  40    cyl   carb 
#> 13           6           6         1           1 100    cyl   carb 
#> 14           8           2         4          10  40    cyl   carb 
#> 15           8           3         3           3 100    cyl   carb 
#> 16           8           4         6          10  60    cyl   carb 
#> 17           8           8         1           1 100    cyl   carb

# Trying to use map to generate sampleOutput
var1_vector=rep("cyl", 2) 
var2_vector=c("gear", "carb")

# Method 1 (recommended): use of anonymous functions
map2(var1_vector, var2_vector, \(var1, var2) ugh(mtcars, var1, var2)) %>%
  list_rbind()
#> # A tibble: 17 × 7
#> # Groups:   Var2_levels [7]
#>    Var1_levels Var2_levels Numerator Denominator    Pct Var1  Var2 
#>          <dbl>       <dbl>     <int>       <int>  <dbl> <chr> <chr>
#>  1           4           3         1          15   6.67 cyl   gear 
#>  2           4           4         8          12  66.7  cyl   gear 
#>  3           4           5         2           5  40    cyl   gear 
#>  4           6           3         2          15  13.3  cyl   gear 
#>  5           6           4         4          12  33.3  cyl   gear 
#>  6           6           5         1           5  20    cyl   gear 
#>  7           8           3        12          15  80    cyl   gear 
#>  8           8           5         2           5  40    cyl   gear 
#>  9           4           1         5           7  71.4  cyl   carb 
#> 10           4           2         6          10  60    cyl   carb 
#> 11           6           1         2           7  28.6  cyl   carb 
#> 12           6           4         4          10  40    cyl   carb 
#> 13           6           6         1           1 100    cyl   carb 
#> 14           8           2         4          10  40    cyl   carb 
#> 15           8           3         3           3 100    cyl   carb 
#> 16           8           4         6          10  60    cyl   carb 
#> 17           8           8         1           1 100    cyl   carb

# If you aren't using a version of R with anonymous functions:
map2(var1_vector, var2_vector, ~ ugh(mtcars, .x, .y)) %>%
  list_rbind()
#> # A tibble: 17 × 7
#> # Groups:   Var2_levels [7]
#>    Var1_levels Var2_levels Numerator Denominator    Pct Var1  Var2 
#>          <dbl>       <dbl>     <int>       <int>  <dbl> <chr> <chr>
#>  1           4           3         1          15   6.67 cyl   gear 
#>  2           4           4         8          12  66.7  cyl   gear 
#>  3           4           5         2           5  40    cyl   gear 
#>  4           6           3         2          15  13.3  cyl   gear 
#>  5           6           4         4          12  33.3  cyl   gear 
#>  6           6           5         1           5  20    cyl   gear 
#>  7           8           3        12          15  80    cyl   gear 
#>  8           8           5         2           5  40    cyl   gear 
#>  9           4           1         5           7  71.4  cyl   carb 
#> 10           4           2         6          10  60    cyl   carb 
#> 11           6           1         2           7  28.6  cyl   carb 
#> 12           6           4         4          10  40    cyl   carb 
#> 13           6           6         1           1 100    cyl   carb 
#> 14           8           2         4          10  40    cyl   carb 
#> 15           8           3         3           3 100    cyl   carb 
#> 16           8           4         6          10  60    cyl   carb 
#> 17           8           8         1           1 100    cyl   carb

# Alternatively, using pmap():
args <- list(
  var1 = var1_vector,
  var2 = var2_vector
)

pmap(args, ugh, mtcars) %>%
  list_rbind()
#> # A tibble: 17 × 7
#> # Groups:   Var2_levels [7]
#>    Var1_levels Var2_levels Numerator Denominator    Pct Var1  Var2 
#>          <dbl>       <dbl>     <int>       <int>  <dbl> <chr> <chr>
#>  1           4           3         1          15   6.67 cyl   gear 
#>  2           4           4         8          12  66.7  cyl   gear 
#>  3           4           5         2           5  40    cyl   gear 
#>  4           6           3         2          15  13.3  cyl   gear 
#>  5           6           4         4          12  33.3  cyl   gear 
#>  6           6           5         1           5  20    cyl   gear 
#>  7           8           3        12          15  80    cyl   gear 
#>  8           8           5         2           5  40    cyl   gear 
#>  9           4           1         5           7  71.4  cyl   carb 
#> 10           4           2         6          10  60    cyl   carb 
#> 11           6           1         2           7  28.6  cyl   carb 
#> 12           6           4         4          10  40    cyl   carb 
#> 13           6           6         1           1 100    cyl   carb 
#> 14           8           2         4          10  40    cyl   carb 
#> 15           8           3         3           3 100    cyl   carb 
#> 16           8           4         6          10  60    cyl   carb 
#> 17           8           8         1           1 100    cyl   carb

相关问题