代码之家  ›  专栏  ›  技术社区  ›  Esther

purrr组合pmap和nest

  •  1
  • Esther  · 技术社区  · 6 年前

    我正在尝试学习purrr,以便在每次迭代中使用不同方法、sd和n的rnorm模拟数据。 此代码生成我的数据帧:

    parameter = crossing(n = c(60,80,100),   
                        agegroup = c("a", "b","c"), 
                        effectsize = c(0.2, 0.5, 0.8),
                        sd =2
                            ) %>%
    # create a simulation id number
    group_by(agegroup) %>%
    mutate(sim= row_number())%>%
    ungroup() %>%
    mutate(# change effect size so that one group has effect, others d=0
           effectsize= if_else(agegroup == "a", effectsize, 0),
           # calculate the mean for the distribution from effect size
           mean =effectsize*sd) 
    

    # create a nested dataframe to iterate over each simulation and agegroup
    nested_df =  parameter %>%
      group_by(sim, agegroup, effectsize)%>%
      nest() %>% arrange(sim)
    

    这就是我的数据帧的外观: picture of dataframe

    现在我想用“数据”列中给出的平均值、sd和n创建正态分布数据

    nested_df = nested_df %>%  
      mutate(data_points = pmap(data,rnorm))
    

    Error in mutate_impl(.data, dots) : 
      Evaluation error: unused arguments 
    

    我读了《数据科学R》中的迭代章节,在谷歌上搜索了一大堆,但我不知道如何将pmap和nest结合起来。我之所以想使用这些函数,是因为它可以更容易地将参数、模拟数据和输出都保存在一个数据帧中。

    0 回复  |  直到 6 年前
        1
  •  3
  •   cautree dipetkov    6 年前

    您不一定需要嵌套参数。例如:

    parameter %>%
      # Use `pmap` because we explicitly specify three arguments
      mutate(data_points = pmap(list(n, mean, sd), rnorm))
    # A tibble: 27 x 7
    #         n agegroup effectsize    sd   sim  mean data_points
    #     <dbl> <chr>         <dbl> <dbl> <int> <dbl> <list>     
    #   1    60 a               0.2     2     1   0.4 <dbl [60]> 
    #   2    60 a               0.5     2     2   1   <dbl [60]> 
    #   3    60 a               0.8     2     3   1.6 <dbl [60]> 
    

    对于嵌套数据框,可以使用 map 而不是 pmap :

    nested_df %>%
      # Use `map` because there is really one argument, `data`,
      # but then refer to three different columns of `data`.
      mutate(data_points = map(data, ~ rnorm(.$n, .$mean, .$sd)))
    
        2
  •  1
  •   Cettt    6 年前

    首先,可以使用 pmap 这样地:

    x <- tibble(n = 100, mean = 5, sd = 0.1)
    pmap(x, rnorm)
    

    do.call :

    do.call(rnorm, x)
    

    但是,如果您想使用 在…内 mutate 您带来了函数的输入 .f 把它做成正确的形状。

    nested_df %>% 
      mutate(y = pmap(x, f))
    

    意味着 f 期望输入 x 在您的例子中,rnorm需要三个输入,但只得到一个。

    因此,如果您坚持嵌套输入,您可以这样做:

    nested_df %>%  
      mutate(data_points = pmap(list(data), function(z) pmap(z, rnorm))[[1]])
    

       nested_df %>%  
          mutate(data_points = pmap(list(data), function(z) do.call(rnorm, z))).
    

    parameter %>% 
      mutate(data_points = pmap(list(n, mean, sd), rnorm))