использовать группирующую переменную в качестве входных данных в функции group_map () - PullRequest
0 голосов
/ 26 мая 2020

У меня есть 30-летний фрейм данных переменной ответа. Я хочу написать код, который будет выполнять подмножество этого df в «x» количество лет «n» раз и запускать регрессию ответа во всех этих подмножествах.

Итак, если бы мы начали с 30 лет, x = 5 & n = 2, мы закончили бы двумя регрессиями, каждая из которых использует 5 случайных лет из имеющихся 30. Я написал функцию для этого здесь:

# build df
df = data.frame(year=c(1:30),
                response = runif(30,1,100))



# create function
subsample <- function(df, x, n ){
  df %>%
    # collaplse the tibble
    nest(data=everything()) %>%

    # repeat the tibble for number of simulations
    slice(rep(1:n(), each = n)) %>%

    # add group number, which will be the "nth" trial
    mutate(group = c(1:n)) %>%

    # expand data
    unnest(cols = c(data)) %>%

    # group by group number, then subsample n times from each group
    group_by(group) %>%
    group_map(~ sample_n(.x, x, replace = F)) %>%

    # stitch back together and add group number col back
    bind_rows(.id="trial") %>%

    # arrange by group and year
    mutate(trial=as.numeric(trial)) %>%
    arrange(trial,year) %>%

    # group by subsample and run regression
    group_by(trial) %>%

    do({
      mod = lm(response ~ year, data = .)
      data.frame(Intercept = coef(mod)[1],
                 Slope = coef(mod)[2])
    }) 
}


# test function
subsample(df, x=5, n=2)


# A tibble: 2 x 3
# Groups:   simulation [2]
      trial   Intercept  Slope
       <dbl>     <dbl>  <dbl>
1          1      48.5 -0.895
2          2      35.4 -0.275

Отлично, так что это работает, и мы получаем две регрессии (все, что мне нужно, это наклон и пересечение), каждая из которых использует подмножество 5 из 30 лет.

Однако теперь я хочу сделать это со всеми возможными комбинациями лет (так x = c (2:30)), заканчивая df, который должен выглядеть так

# A tibble: 2 x 3
   number_of_years    trial   Intercept  Slope
        <dbl>         <dbl>     <dbl>  <dbl>
1         2             1      48.5 -0.895
2         2             2      35.4 -0.275
3         3             1      55.2  0.333
4         3             2      34.1  0.224
5         4             1      63.2 -0.359
6         4             2      45.5 -0.241
7         5             1      43.1  0.257
8         5             2      37.9 -0.657
9         6             1      51.0 -0.456
10        6             2      65.6  0.126     

Это будет показывать значения регрессии 2 испытаний («n»), каждое из которых использует 2 случайных года (number_of_years, «x»), затем 2 испытания, используя 3 случайных года, 4 случайных года и т. Д. c ... все путь до 30.

Итак, я попытался следовать тому же logi c, как указано выше, но теперь пытаюсь map_group() с созданной мной настраиваемой функцией:


df %>%
  # collaplse the tibble
  nest(data=everything()) %>%

  # repeat the tibble for the number of simulations we want to test (29, in this case)
  slice(rep(1:n(), each = (nrow(df)-1))) %>%

  # add column for number out of total and unnest
  mutate(number_of_years = c(2:(nrow(.)+1))) %>% 
  select(number_of_years,data) %>%  #reorder
  unnest(cols =c(data)) %>%

  # group by out of total
  group_by(number_of_years) %>%

  group_map( ~ subsample(.x, x=5, n=2,))
  ### this is the problematic line! 
  ### this is giving us 2 trials (n=2) of a regression, each using 
  ### x=5 years of sampling. but instead of x=5 years, I want x=number_of_years
  ### so x should be the same as the grouping variable. 

Итак, проблема так как моей функции subsample () требуется 3 входа (df, x, n), мне нужно выяснить, как сделать «x» таким же, как переменная группировки для набора данных. x должно быть (число_лет). Я пытался сделать group_map( ~ subsample(.x,.x$number_of_years,2) и подобные ему варианты, но я не могу понять, как заставить его возвращать 30 таблиц по 2 испытания в каждом, что означает 2 регрессии подвыборок исходного df, но каждая из них использует другое число лет для расчета регрессии.

Я бы хотел остаться в рабочем процессе tidyverse / dplyr / purr, если это возможно.

Спасибо!

...