Как применить мутировать только к подмножеству строк, но при этом создавать новый столбец для каждого наблюдения?

#r #dplyr

Вопрос:

У меня есть фрейм данных с 60 наблюдениями за последовательными инвестиционными решениями, принятыми некоторыми участниками. Каждое инвестиционное решение-это число от 0 до 100. Мой фрейм данных организован таким образом:

 subjet_id | period |  invest  |
1      |  1     | 42%         |
1      |  2     | 13%         |
1      |  ...   | 72%         |
1      |  60    | 18%         |
2      |  1     | 52%         |
2      |  ...   | 42%         |
2      |  60    | 18%         |
3      |  1     | 25%         |
 

Я знаю, как создать новую колонку со средним значением инвестиций для каждой темы:

 dataframe = dataframe %>% group_by(subjet_id) %>% mutate(mean_invest = mean(invest))
 

Теперь я хочу разделить свои периоды между «краткосрочными» (периоды с 1 по 30) и «долгосрочными» (периоды с 31 по 60). Я хотел бы иметь одну новую строку для среднего значения инвестиций каждого участника как в краткосрочной, так и в долгосрочной перспективе. Я хочу что-то подобное (цифры не точны):

 subjet_id | period |  invest  | invest_mean | short_run_mean | long_run_mean  |
1      |  1     | 42%         | 25%         | 15%            | 25%            |
1      |  2     | 13%         | 25%         | 15%            | 25%            |
1      |  ...   | 72%         | 25%         | 15%            | 25%            |
1      |  60    | 18%         | 35%         | 45%            | 25%            |
2      |  1     | 52%         | 35%         | 45%            | 25%            |
2      |  ...   | 42%         | 35%         | 45%            | 25%            |
2      |  60    | 18%         | 35%         | 45%            | 25%            |
3      |  1     | 25%         | 30%         | 20%            | 30%            |
 

Проблема в том, что я не могу просто сделать a filter(periods < 30)
и a mutate (short_run_mean = mean(invest)) , потому что у меня будут значения short_run_mean только для периодов :

 subjet_id | period |  invest  | invest_mean | short_run_mean | long_run_mean  |
1      |  1     | 42%         | 25%         | 15%            | ---            |
1      |  2     | 13%         | 25%         | 15%            | ---            |
1      |  ...   | 72%         | 25%         | 15%            | ---            |
1      |  60    | 18%         | 35%         | ---            | 25%            |
2      |  1     | 52%         | 35%         | 45%            | ---            |
2      |  ...   | 42%         | 35%         | 45%            | ---            |
2      |  60    | 18%         | 35%         | ---            | 25%            |
3      |  1     | 25%         | 30%         | 20%            | ---            |
 

Поэтому я хотел бы применить функцию mean только к подмножеству моего фрейма данных и добавить результат в каждую строку в качестве новой переменной.

Любая идея о том, как я могу сделать это с помощью обычных функций R (я знаю, что могу использовать для циклов и тому подобного, но я ищу функциональное решение!).

Ответ №1:

 df <- read.table(textConnection('subjet_id | period |  invest  
1      |  1     | 0.42         
1      |  2     | 0.13          
1      |  60    | 0.18        
2      |  1     | 0.52           
2      |  60    | 0.18         
3      |  1     | 0.25         
'),header=T,sep='|')

library(dplyr)

df2 <- df %>%
group_by(subjet_id) %>%
mutate(invest_mean=mean(invest)) %>%
ungroup %>%
mutate(period_type=ifelse(period>=1 amp; period<=30,'short_run','long_run')) %>%
group_by(subjet_id,period_type) %>%
mutate(short_run_mean=ifelse(period_type=='short_run',mean(invest),NA)) %>%
mutate(long_run_mean=ifelse(period_type=='long_run',mean(invest),NA)) %>%
ungroup %>%
select(-period_type)

df2
 

выход;

   subjet_id period invest invest_mean short_run_mean long_run_mean
      <dbl>  <dbl>  <dbl>       <dbl>          <dbl>         <dbl>
1         1      1   0.42       0.243          0.275         NA   
2         1      2   0.13       0.243          0.275         NA   
3         1     60   0.18       0.243         NA              0.18
4         2      1   0.52       0.35           0.52          NA   
5         2     60   0.18       0.35          NA              0.18
6         3      1   0.25       0.25           0.25          NA