#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 мы вам очень рады. Пожалуйста, ознакомьтесь с моим обновлением, дайте мне знать, если вам потребуется дополнительная информация.