我正在尝试学习purrr以在每次迭代中使用具有不同均值,sd和n的rmrm模拟数据。 这段代码生成了我的数据框:
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根据均值,sd和r生成数据
# create a nested dataframe to iterate over each simulation and agegroup
nested_df = parameter %>%
group_by(sim, agegroup, effectsize)%>%
nest() %>% arrange(sim)
现在,我要创建“数据”列中给出的均值,sd和n的正态分布数据。
nested_df = nested_df %>%
mutate(data_points = pmap(data,rnorm))
但是上面的代码给出了一个我无法找到解决方案的错误:
Error in mutate_impl(.data, dots) :
Evaluation error: unused arguments
我阅读了R for Data Science中的“迭代”一章,并用Google搜索了一堆,但是我不知道如何将pmap和nest结合起来。我之所以要使用这些功能,是因为它可以更轻松地将参数,模拟数据以及所有输出保留在一个数据帧中。
答案 0 :(得分:2)
您不一定需要嵌套参数。例如:
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 :(得分:1)
首先,可以像这样使用pmap
:
x <- tibble(n = 100, mean = 5, sd = 0.1)
pmap(x, rnorm)
与使用do.call
非常相似:
do.call(rnorm, x)
但是,如果要在pmap
中使用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))
希望这会有所帮助。