Циклические месячные индексы за конкретный год - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть формат данных, такой как прикрепленное изображение ниже, где у нас есть данные о продажах разных SKU за несколько лет, распределенные ежемесячно.

Input file format

Iвычислили месячные индексы для каждого года с помощью функции;

calc_monthly_all<- function(X){
  X$sku <- as.character(X$sku)
  X$Yearly_Avg <- rowMeans(X[,-c(1:2)])
  level_one <- X %>% dplyr::mutate_at(vars(starts_with('Month_')), funs(./Yearly_Avg))
  return(level_one)
  }

Отображаемые данные читаются как 'df_data' в R, и после применения функции вывод выглядит как показано ниже,

> calc_monthly_all(df_data)
             sku Year  Month_Jan  Month_Feb Month_March Month_April Month_May Month_June Month_July Month_Aug Month_Sept
1 10929000284004 2015 0.32601608 0.19821778   0.6755053   2.0838948 0.5398826  1.7657031  1.2414692 1.1136709  0.6650728
2 10929000284004 2016 0.92209048 2.52811562   1.4961071   1.8380744 0.6534019  0.7511068  0.5190576 0.2992214  0.1038115
3 10929001124004 2014 0.04678503 0.04318618   0.4847649   0.9385797 0.9781670  0.9353407  0.7924664 1.2894674  1.2070537
4 10929001124004 2015 1.40699537 1.86480849   0.7979080   0.7520179 0.3975936  1.1719218  0.4233502 0.6419178  1.5749569
5 10929001124004 2016 0.92209048 2.52811562   1.4961071   1.8380744 0.6534019  0.7511068  0.5190576 0.2992214  0.1038115
6 10929001124104 2016 1.00160192 0.65078094   0.8191163   0.8358030 1.0112802  0.9419971  0.7209318 1.0449873  1.0337071
7 10929001124104 2017 0.83334681 0.74955923   0.7739514   1.2059589 1.1626741  1.4993773  1.0948676 0.9872054  1.1436520
  Month_Oct Month_Nov Month_Dec Yearly_Avg
1 1.5831341 1.1945229 0.6129102   3834.167
2 1.2029922 0.5434838 1.1425373   1637.583
3 2.2273273 1.7357246 1.3211372  27786.667
4 0.9569818 0.6437317 1.3678164  55131.667
5 1.2029922 0.5434838 1.1425373   1637.583
6 1.3110399 1.3426111 1.2861434 149820.000
7 0.9806706 0.8718438 0.6968927 154557.500

Теперь, для каждого года каждого SKU, мы получили месячные индексы.Теперь нам нужно взять индексы за один конкретный год, скажем, за первый год.Это означает, что для каждого SKU мы будем брать ежемесячные индексы для соответствующего первого года, возвращать фрейм данных, содержащий только месячные индексы первого года для каждого SKU.Для этого я попытался;

calc_monthly_fys<- function(X){
  X$sku <- as.character(X$sku)
  X$Yearly_Avg <- rowMeans(X[,-c(1:2)])
  level_one <- X %>% dplyr::mutate_at(vars(starts_with('Month_')), funs(./Yearly_Avg))
  first_yr_store <- data.frame()
  for (i in unique(level_one$sku)){
    fys1 <- subset(level_one,sku %in% i)
    fys <- fys1[1,]
    df <-data.frame(fys)
    df_total <- rbind(first_yr_store,df)
    return(df_total)
  }
} 

, но он не дает должного результата, появляется только первый SKU.

calc_monthly_fys(df_data)
             sku Year Month_Jan Month_Feb Month_March Month_April Month_May Month_June Month_July Month_Aug Month_Sept
1 10929000284004 2015 0.3260161 0.1982178   0.6755053    2.083895 0.5398826   1.765703   1.241469  1.113671  0.6650728
  Month_Oct Month_Nov Month_Dec Yearly_Avg
1  1.583134  1.194523 0.6129102   3834.167

Мне это нужно для всех SKU.

Здесь пример имеет 3 уникальных SKU, но данные могут иметь n 'количество SKU.Наконец, вывод, который мне нужен, должен быть в следующем формате:

Final Table output

Имена столбцов (от SKU_1 до SKU_N) должны приходить динамически (если мы имеемчетыре уникальных SKU, при этом четыре названия SKU должны отображаться как имена столбцов)._FYI указывает здесь «индекс первого года», я думаю, что мы можем использовать функцию paste для добавления суффикса _FYI после каждого уникального имени SKU в итоговой выходной таблице.

Пожалуйста, помогите мне генерировать ежемесячноиндексы в обсуждаемом формате для N количества SKU & M количество лет.

TIA

1 Ответ

0 голосов
/ 28 февраля 2019

Не совсем понятно, как вы хотите относиться к разным годам для каждого SKU, но это может помочь.

Предполагается, что df содержит то, что вы показали в результате вашего calc_monthly_all(df_data) вызова.

# Get rid of the yearly average, as it's not needed in the results
df$Yearly_Avg <- NULL

# We're going to transpose the dataframe  (turn the rows into columns,
# and the columns into rows), so make the row names what will be the 
# column names
rownames(df) <- paste0(df$sku, '_', df$Year)

# Get rid of the unnecessary sku and year columns, as they're not needed
# if we leave them, the transpose will coerce all the columns to characters
df$sku <- NULL
df$Year <- NULL

# Transpose the dataframe
df2 <- t(df)

# Get rid of "Month_" at the start of the rownames
rownames(df2) <- gsub('^Month_', '', rownames(df2))

# View the results
df2

РЕДАКТИРОВАТЬ

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

library(dplyr)

calc_monthly_all<- function(X){
  X$sku <- as.character(X$sku)
  X$Yearly_Avg <- rowMeans(X[,-c(1:2)])
  level_one <- X %>% dplyr::mutate_at(vars(starts_with('Month_')), funs(./Yearly_Avg))

  level_one$Yearly_Avg <- NULL

  rownames(level_one) <- paste0(level_one$sku, '_', level_one$Year)
  level_one$sku <- NULL
  level_one$Year <- NULL

  result <- t(level_one)
  rownames(result) <- gsub('^Month_', '', rownames(result))
  result
}

РЕДАКТИРОВАТЬ 2 Если вы просто хотите получить данные за один год, вы должны отфильтровать функцию перед выполнением транспонирования:

library(dplyr)

calc_monthly_one_year<- function(X, required_year){
  X <- X %>% filter(Year == required_year)

  X$sku <- as.character(X$sku)
  X$Yearly_Avg <- rowMeans(X[,-c(1:2)])
  level_one <- X %>% dplyr::mutate_at(vars(starts_with('Month_')), funs(./Yearly_Avg))

  level_one$Yearly_Avg <- NULL

  rownames(level_one) <- level_one$sku
  level_one$sku <- NULL
  level_one$Year <- NULL

  result <- t(level_one)
  rownames(result) <- gsub('^Month_', '', rownames(result))
  result
}

calc_monthly_one_year(df_data, 2016)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...