purrr结合pmap和nest

4
我正在尝试学习 purrr,使用 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) 

现在我想迭代不同的模拟,对于每一行,使用rnorm按照均值、标准差和r生成数据。
# 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
现在我想要创建均值、标准差和 n 在“data”列中给出的正态分布数据。
nested_df = nested_df %>%  
  mutate(data_points = pmap(data,rnorm))

然而,上述代码会出现一个错误,我还没有找到解决方法:
Error in mutate_impl(.data, dots) : 
  Evaluation error: unused arguments 

我读了《R数据科学》中的迭代章节并进行了一些谷歌搜索,但我无法弄清楚如何将pmap和nest结合起来使用。我之所以想使用这些函数是因为它们可以更容易地将参数、模拟数据和输出全部放在一个数据框中。
2个回答

3

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

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

1
首先,像这样使用pmap是可以的:
x <- tibble(n = 100, mean = 5, sd = 0.1)
pmap(x, rnorm)

这与使用do.call非常相似:

do.call(rnorm, x)

然而,如果您想在mutate中使用pmap,您需要将函数.f的输入转换为正确的形状。保留HTML标签。
nested_df %>% 
  mutate(y = pmap(x, f))

意味着 f 需要输入 x。在你的情况下,rnorm 需要三个输入,但只得到一个。

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

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

or

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

然而,我建议稍微以不同的方式进行:

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

希望这能帮到你一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接