Как программно выбрать столбцы для изменения? - PullRequest
0 голосов
/ 10 июня 2019

Пример данных:

Project  2016   2017   2018   2019
Proj1      42     36    400    250
Proj2      96    780     60    900
Proj3     180    230      0      0

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

В данных есть столбцы, помеченные как 2016, 2017, 2018, 2019 ... и т. Д.

Totals<-Totals %>% mutate("Previous Years"=`2016`+`2017`+`2018`)

Теперь я пытаюсь настроить это так, чтобы я мог выбрать это программно;в следующем году я предпочел бы посмотреть на данные за 2017, 2018 и 2019 годы, естественно, и я хотел бы просто настроить их так, чтобы я мог ввести номер года, и он выберет правильные столбцы с помощью кода.

year = 2019

index<-which(colnames(Totals)==year)

Totals<-Totals%>%
##Here's where it gets hairy
mutate("Previous Years"=Totals[index-3]+Totals[index-2]+Totals[index-1])

Error: Column `Previous Years` is of unsupported class data.frame

Итак, есть некоторые проблемы.Очевидно, что я что-то неправильно называю, сценарий 1 выше работает как чудо, а второй сценарий выдает ошибку.Я чувствую, что это как-то связано с обратными галочками, которые вы обычно используете для вызова столбцов с необычными именами в dplyr.

Как правильно сделать что-то подобное?

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Я не думаю, что ваши данные аккуратны. Все станет проще, если вы сделаете это аккуратно. Например:

Чтение данных

library(dplyr)
library(tidyr)

Totals <- data.table::fread('Project  2016   2017   2018   2019
Proj1     $42    $36   $400   $250
Proj2     $96   $780    $60   $900
Proj3    $180   $230     $0     $0', header = TRUE)

year <- 2019

Приведите в порядок и рассчитайте предыдущее финансирование.

summ <- Totals %>% 
  gather(Year, Funding, -Project) %>% 
  mutate(Funding = readr::parse_number(Funding)) %>% 
  group_by(Project) %>% 
  summarise(Previous_funding = sum(Funding[Year %in% (year - 3):(year - 1)]))
# A tibble: 3 x 2
  Project Previous_funding
  <chr>              <dbl>
1 Proj1                478
2 Proj2                936
3 Proj3                410

Вы также можете использовать mutate вместо summarise для хранения всех данных:

# A tibble: 12 x 4
# Groups:   Project [3]
   Project Year  Funding Previous_funding
   <chr>   <chr>   <dbl>            <dbl>
 1 Proj1   2016       42              478
 2 Proj2   2016       96              936
 3 Proj3   2016      180              410
 4 Proj1   2017       36              478
 5 Proj2   2017      780              936
 6 Proj3   2017      230              410
 7 Proj1   2018      400              478
 8 Proj2   2018       60              936
 9 Proj3   2018        0              410
10 Proj1   2019      250              478
11 Proj2   2019      900              936
12 Proj3   2019        0              410

Или, если хотите, можете добавить предыдущее финансирование обратно в исходный широкий стол:

left_join(Totals, summ, 'Project')
 Project 2016 2017 2018 2019 Previous_funding
1   Proj1  $42  $36 $400 $250              478
2   Proj2  $96 $780  $60 $900              936
3   Proj3 $180 $230   $0   $0              410
0 голосов
/ 10 июня 2019

Используя данные вашего примера,

library(tidyverse)

adf <- tibble(
  project = c("pro1","pro2","pro3"),
  `2016` = c(42,96,180),
  `2017` = c(36,780,230),
  `2018` = c(400,60,0),
  `2019` = c(250,900,0)
)

Теперь давайте напишем функцию, которая добавит сумму, заданную указанным годом

previous <- function(data, year){
  data%>%gather(Year, Funding, -project)%>%
    mutate_at(vars(Year), list(~as.numeric(.)))%>%
    split(.$project)%>%
    map(~(.)%>%filter(Year < 
    year)%>%summarise(UQ(paste0("Prior_to_",as.character(year))) := 
    sum(Funding)))%>%bind_rows()%>%
    bind_cols(data,.)
}

Теперь давайте добавим новый столбец с суммойфинансирования за годы до 2018 года.

> previous(data = adf, year = 2018)
# A tibble: 3 x 6
  project `2016` `2017` `2018` `2019` Prior_to_2018
  <chr>    <dbl>  <dbl>  <dbl>  <dbl>         <dbl>
1 pro1        42     36    400    250            78
2 pro2        96    780     60    900           876
3 pro3       180    230      0      0           410
>

Вы также можете использовать group_by() в функции следующим образом:

previous <- function(data, year){
  data%>%gather(Year, value, -project)%>%
    mutate_at(vars(Year), list(~parse_number(.)))%>%
    group_by(project)%>%
    summarise(UQ(paste0("Prior_to_",as.character(year))) := 
sum(value[Year < year]))%>%
    left_join(data, ., by = 'project')
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...