在函数中使用www.example.com()更正R map()函数的参数规范do.call

qjp7pelc  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(122)

我一直在学习一门在线课程,我的练习涉及到使用rlang函数来生成所需的输出,建议的解决方案涉及到使用for()循环,但由于课程的前一部分涉及到purrr和map(),因此求助于for()循环似乎是一种倒退。
我有一个小问题:(命名为"参数")

# A tibble: 15 × 2
   fname .args                
   <chr> <chr>                
 1 rnorm n=10,mean=0,sd=3     
 2 rnorm n=100,mean=0,sd=3    
 3 rnorm n=1000,mean=0,sd=3   
 4 rnorm n=10000,mean=0,sd=3  
 5 rnorm n=100000,mean=0,sd=3 
 6 runif n=10,min=0,max=10    
 7 runif n=100,min=0,max=10   
 8 runif n=1000,min=0,max=10  
 9 runif n=10000,min=0,max=10 
10 runif n=100000,min=0,max=10
11 rexp  n=10,rate=2          
12 rexp  n=100,rate=2         
13 rexp  n=1000,rate=2        
14 rexp  n=10000,rate=2       
15 rexp  n=100000,rate=2

我写了这个函数:

demo_1 <- function(func_name, arg_list){
   do.call(func_name, arg_list)
}

如果我这样调用函数:

demo_1(arguments$fname[[1]], as.list(strsplit(arguments$.args[[1]],",")))

我得到了预期的输出:[1] -0.4454785 0. 6222901 -1.3134630
一周来我一直在努力将这些内容传递给map(),但还是没能解决这个问题,我该如何将这些内容传递给map()来逐行处理整个tibble呢?
谢谢。

f4t66c6m

f4t66c6m1#

使用rowwise

library(dplyr)
arguments %>% 
  rowwise %>%
  mutate(new = list(demo_1(fname,  as.list(strsplit(.args,","))))) %>%
  ungroup
  • 输出
# A tibble: 15 × 3
   fname .args                 new      
   <chr> <chr>                 <list>   
 1 rnorm n=10,mean=0,sd=3      <dbl [3]>
 2 rnorm n=100,mean=0,sd=3     <dbl [3]>
 3 rnorm n=1000,mean=0,sd=3    <dbl [3]>
 4 rnorm n=10000,mean=0,sd=3   <dbl [3]>
 5 rnorm n=100000,mean=0,sd=3  <dbl [3]>
 6 runif n=10,min=0,max=10     <dbl [3]>
 7 runif n=100,min=0,max=10    <dbl [3]>
 8 runif n=1000,min=0,max=10   <dbl [3]>
 9 runif n=10000,min=0,max=10  <dbl [3]>
10 runif n=100000,min=0,max=10 <dbl [3]>
11 rexp  n=10,rate=2           <dbl [2]>
12 rexp  n=100,rate=2          <dbl [2]>
13 rexp  n=1000,rate=2         <dbl [2]>
14 rexp  n=10000,rate=2        <dbl [2]>
15 rexp  n=100000,rate=2       <dbl [2]>

更新

通过仔细查看OP的函数参数,发现输出不正确。即,对于第一行,它应返回10个观察结果n = 10(仅显示前2行的输出,因为其他行的n值较大)

library(purrr)
arguments %>%
   slice(1:2) %>%
    mutate(new = pmap(pick(everything()),
   ~ eval(rlang::parse_expr(sprintf('%s(%s)', ..1, ..2))))) %>%
    as_tibble
  • 输出
# A tibble: 2 × 3
  fname .args             new        
  <chr> <chr>             <list>     
1 rnorm n=10,mean=0,sd=3  <dbl [10]> 
2 rnorm n=100,mean=0,sd=3 <dbl [100]>

或者不使用eval/parse

library(tidyr)
arguments %>% 
  mutate(rn = row_number())  %>% 
  slice(1:2)  %>%
  separate_longer_delim(`.args`, delim=",") %>% 
  separate_wider_delim(`.args`, names = c("arg_name", "value"), delim = "=") %>% 
 type.convert(as.is = TRUE) %>% 
 reframe(fname = first(fname), 
   value = list(as.list(setNames(value, arg_name))), .by = 'rn') %>% 
 rowwise %>% 
 mutate(new = list(demo_1(fname, value))) %>%
 ungroup
  • 输出
# A tibble: 2 × 4
     rn fname value            new        
  <int> <chr> <list>           <list>     
1     1 rnorm <named list [3]> <dbl [10]> 
2     2 rnorm <named list [3]> <dbl [100]>

数据

arguments <- structure(list(fname = c("rnorm", "rnorm", "rnorm", "rnorm", 
"rnorm", "runif", "runif", "runif", "runif", "runif", "rexp", 
"rexp", "rexp", "rexp", "rexp"), .args = c("n=10,mean=0,sd=3", 
"n=100,mean=0,sd=3", "n=1000,mean=0,sd=3", "n=10000,mean=0,sd=3", 
"n=100000,mean=0,sd=3", "n=10,min=0,max=10", "n=100,min=0,max=10", 
"n=1000,min=0,max=10", "n=10000,min=0,max=10", "n=100000,min=0,max=10", 
"n=10,rate=2", "n=100,rate=2", "n=1000,rate=2", "n=10000,rate=2", 
"n=100000,rate=2")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15"))

相关问题