Мин Нормализация по условию - PullRequest
0 голосов
/ 01 ноября 2018

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

df

  Market  Week Sales  diff_data1    another2
1      1     1     5          30         -40
2      1     2     4           7          -8
3      1     3     7         100           9
4      1     4    11          92          50
5      2     1     8           0           8
6      2     2     5           0          14
7      2     3     8           9          98
8      2     4     1           3           3

Моя цель - нормализовать данные двумя разными способами: средняя нормализация и минимальная нормализация. Средняя нормализация сделана для данных о продажах, в то время как минимальная нормализация сделана для не-продаж. Я думаю, что у меня есть правильная средняя нормализация, но минимальная нормализация немного сложнее, потому что у меня есть условия для выбранных данных. Ниже то, что я имею в настоящее время.

##Function to standardizing variables
group = "Market"
date = "Week"

##Function to standardize sales by dividing by the standard deviation of sales
normalized_mean <- function(x){
  return(x/(sd(x)))
}

##Function to standardize variables by subtracting min
##Used for non-sales data
normalized_min<-function(x){
  out<- ifelse(x>0, ((x-min(x)) / sd(x)),
               ifelse(x<0, ((x+max(x)) / sd(x)), 
                      ifelse(x==0, 0,0)))
  return(out)
}

if (!("Sales" %in% colnames(df))){
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_min)
} else {
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_mean)

}

Текущий выход этого:

df_index

  Market  Week Sales  diff_data1   another2
1      1     1 1.62        0.655     -1.07  
2      1     2 1.29        0.153     -0.213 
3      1     3 2.26        2.18       0.240 
4      1     4 3.55        2.01       1.33  
5      2     1 2.41        0          0.178 
6      2     2 1.51        0          0.311 
7      2     3 2.41        2.12       2.17  
8      2     4 0.302       0.707      0.0666

Вывод должен быть таким:

  Market  Week Sales  diff_data1    another2
1      1     1 1.62        0.501     0.26679  
2      1     2 1.29            0     1.12053
3      1     3 2.26         2.02     1.30729
4      1     4 3.55         1.85     2.40114 
5      2     1 2.41            0     7.93342
6      2     2 1.51            0     13.9334
7      2     3 2.41        2.121     97.9334
8      2     4 0.302       0.707     2.93342

Моя проблема заключается в следующей формуле.

Как мне заставить условия работать для такого рода примера? Похоже, что он не принимает во внимание условия x>0, x<0 и x==0.

normalized_min<-function(x){
  out<- ifelse(x>0, ((x-min(x)) / sd(x)),
               ifelse(x<0, ((x+max(x)) / sd(x)), 
                      ifelse(x==0, 0,0)))
  return(out)
}

Любая помощь была бы отличной, спасибо!

1 Ответ

0 голосов
/ 01 ноября 2018

Работает нормально с удалением восклицательного знака перед "Продажами", думаю, у вас есть опечатка:

if ("Sales" %in% colnames(df)){
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_min)
} else {
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_mean)

}

Выход:

  Market  Week Sales diff_data1 another2
   <int> <int> <dbl>      <dbl>    <dbl>
1      1     1 0.323      0.502    0.267
2      1     2 0          0        1.12 
3      1     3 0.969      2.03     1.31 
4      1     4 2.26       1.85     2.40 
5      2     1 2.11       0        0.111
6      2     2 1.21       0        0.244
7      2     3 2.11       2.12     2.11 
8      2     4 0          0.707    0 

Это, конечно, зависит от того, чего вы действительно хотите.

В вашем описании кажется, что он должен вычислять нормализованное среднее значение (что действительно является тем, что вы также получаете в своих выходных данных), но из вашего примера кажется, что всякий раз, когда есть продажи в именах, он должен начать вычислять нормализованный минимум.

Если вы удалите столбец «Продажи» из своего набора данных, он также будет отлично работать с вашей начальной функцией:

df <- df[,-3]


if (!("Sales" %in% colnames(df))){
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_min)
} else {
  df_index<-df %>% 
    dplyr::group_by(!!sym(group)) %>% 
    dplyr::mutate_at(vars(-one_of(!!group,!!date)), normalized_mean)

}

  Market  Week diff_data1 another2
   <int> <int>      <dbl>    <dbl>
1      1     1      0.502    0.267
2      1     2      0        1.12 
3      1     3      2.03     1.31 
4      1     4      1.85     2.40 
5      2     1      0        0.111
6      2     2      0        0.244
7      2     3      2.12     2.11 
8      2     4      0.707    0   
...