мурлыканье объединяет pmap и гнездо - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь научиться мурлыкать для симуляции данных, используя rnorm с разными средствами, sd и n в каждой итерации.Этот код генерирует мой фрейм данных:

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) 

Теперь я хочу перебрать различные симуляции и для каждой строки сгенерировать данные в соответствии со средним, sd и r, используя rnorm

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

Thisтак выглядит мой фрейм данных: picture of dataframe

Теперь я хочу создать нормально распределенные данные со средним, sd и 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 ]

0 голосов
/ 03 марта 2019

во-первых, можно использовать 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))

Надеюсь, это немного поможет.

0 голосов
/ 03 марта 2019

Вам не обязательно вкладывать параметры.Например:

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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...