Начать с определенного столбца и перейти к определенному количеству столбцов на основе условий в R

#r #dplyr #tidyr

#r #dplyr #tidyr

Вопрос:

У меня есть приведенные ниже данные в широком формате, где каждая строка представляет демонстрационный зал, квартал — с какого квартала демонстрационный зал начал продавать, а начальный год — финансовый год начала.

 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                                                                               
  

Для каждого агента я должен начать со столбца, основанного на квартале и начальном году (Quarter2_Num.16-17 ФГ для row1) и охватить период в год, который в данном случае будет означать Quarter2_Num.17-18ФГ.
Как можно видеть, названия столбцов основаны на квартале и начальном году.

В конечном итоге я пытаюсь получить:

 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 я могу получить столбцы, содержащие FY16-17 или FY17-18. Но я не уверен, как указать начальный столбец для каждой строки, а затем выполнить обход для N строк.

Кто-нибудь, пожалуйста, может мне помочь с этим?

Комментарии:

1. Почему для вывода 2-й строки начинается со столбца, Quarter3_Num.FY16-17 когда в нем есть Quarter = 3 и StartingYear = FY17-18 ?

2. Всегда ли столбцы вашего фрейма данных расположены в правильном порядке (q1.y1, q2, y1, q3, y1, q4.y1, q1.y2 и так далее)?

3. Привет @TinglTanglBob .. да, это всегда упорядочивается аналогичным образом

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

Ответ №1:

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

 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 amp; 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 но вы получите NAs для 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"
      

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

  • Комментарии:

    1. Привет @A Suliman.. Не могли бы вы, пожалуйста, объяснить часть gsub: мутировать (Quar= gsub(‘Quarter(\ d)_.*’,’\1′, k),year=gsub(‘Квартал \d_Num\.(.*)\.(.*)’,’\1-\2′, k)) %>% . Возможно, я захочу изменить этот код на месяц вместо квартала, поэтому я бы попросил вас любезно объяснить, что делает код!

    2. @ShuvayanDas мы вам очень рады. Пожалуйста, ознакомьтесь с моим обновлением, дайте мне знать, если вам потребуется дополнительная информация.