Начните с определенного столбца и перейдите к определенному количеству столбцов на основе условий в R - PullRequest
0 голосов
/ 12 марта 2019

У меня есть следующие данные в широком формате, где каждая строка представляет выставочный зал, Квартал - это квартал, с которого начались продажи выставочного зала, а Начальный год - финансовый год начала.

Code    Quarter StartingYear Quarter1_Num.FY16-17 Quarter2_Num.FY16-17 Quarter3_Num.FY16-17 Quarter4_Num.FY16-17 Quarter1_Num.FY17-18 Quarter2_Num.FY17-18 Quarter3_Num.FY17-18 Quarter4_Num.FY17-18 
S2249       2   FY16-17         0                       23                  0                   0                   2                       0                   6                   0
S463        3   FY17-18         0                       0                   4                   0                   0                       4                   90                  8                                                                               

Для каждого агента:Я должен начать со столбца на основе Quarter & Starting Year (Quarter2_Num.FY16-17 для row1) и охватить период года, который в этом случае будет означать Quarter2_Num.FY17-18.Как видно, имена столбцов основаны на Quarter и StartingYear.

Ouput Я пытаюсь получить:

Code    Quarter1_Starting_Num Quarter2_Starting_Num Quarter3_Starting_Num Quarter4_Starting_Num Quarter5_Starting_Num
S2249       23                  0                       0                   2                       0
S463        4                   0                       0                   4                       90  

Столбцы собирают данные за год по кварталам после выставочного зала.начало.

Я знаю, что с помощью gsub я могу получить столбцы, содержащие 16-17 ФГ или 17-18 ФГ.Но я не уверен, как указать начальный столбец для каждой строки, а затем выполнить обход для N строк.

Может кто-нибудь помочь мне с этим?

1 Ответ

1 голос
/ 12 марта 2019

Сначала мы переносим набор данных с широкого на длинный, а затем выполняем наши вычисления и, наконец, фильтры преобразуем его обратно в широкоформатный.

library(dplyr)
library(tidyr)
gather(df, k,val,-c(Code,Quarter,StartingYear)) %>% 
mutate(Quar=gsub('Quarter(\\d)_.*','\\1',k),year=gsub('Quarter\\d_Num\\.(.*)\\.(.*)','\\1-\\2',k)) %>% 
arrange(Code) %>% group_by(Code) %>% 
mutate(flag=cumsum(cumsum(Quarter==Quar & StartingYear==year)), Quarter1=paste0('Quarter',flag,'_Starting_Num')) %>% 
filter(between(flag,1,5)) %>% select(Code,Quarter1,val) %>% spread(Quarter1,val)

# A tibble: 2 x 6
# Groups:   Code [2]
   Code  Quarter1_Starting_Num Quarter2_Starting_Num Quarter3_Starting_Num Quarter4_Starting_Num Quarter5_Starting_Num
  <fct>                 <int>                 <int>                 <int>                 <int>                 <int>
1 S2249                    23                     0                     0                     2                     0
2 S463                      4                     0                     0                     4                    90

Данные

df <- structure(list(Code = structure(1:2, .Label = c("S2249", "S463"
), class = "factor"), Quarter = 2:3, StartingYear = structure(c(1L, 
1L), .Label = "FY16-17", class = "factor"), Quarter1_Num.FY16.17 = c(0L, 
0L), Quarter2_Num.FY16.17 = c(23L, 0L), Quarter3_Num.FY16.17 = c(0L, 
4L), Quarter4_Num.FY16.17 = c(0L, 0L), Quarter1_Num.FY17.18 = c(2L, 
0L), Quarter2_Num.FY17.18 = c(0L, 4L), Quarter3_Num.FY17.18 = c(6L, 
90L), Quarter4_Num.FY17.18 = c(0L, 8L)), class = "data.frame", row.names = c(NA, 
-2L))

PS: я изменил S463 3 FY17-18 на S463 3 FY16-17, чтобы соответствовать ожидаемому результату, вы можете оставить S463 3 FY17-18, но вы получите NA для Q3 до Q5

gsub('Quarter(\\d)_.*','\\1',c('Quarter1_Num.FY16.17','Quarter4_Num.FY17.18'))
[1] "1" "4"

'Quarter(\\d)_.*' сгруппировать одну цифру, т. Е. 1-9 после четверти и до _, и вернуть эту группу, используя \\1
gsub('Quarter\\d_Num\\.(.*)\\.(.*)','\\1-\\2',c('Quarter1_Num.FY16.17','Quarter4_Num.FY17.18'))
[1] "FY16-17" "FY17-18"

\\. пропустить буквальную точку после Quarter, за которой следует digit_Num. В регулярном выражении мы пропускаем специальные символы, такие как ., используя \\ (.*) сгруппировать все, что угодно, после точки и до следующей точки в одну группу, т.е. gsub будет рассматривать это как группу 1 \\. пропустить буквальную точку (.*) сгруппируйте что-нибудь после точки в одну группу, то есть 17 и 18, gsub будет рассматривать это как группу 2 \\1-\\2 возврат группы 1 и группы 2, разделенных на -, т. Е. 16-17 финансовых годов
...