Как получить значения тренда из разных временных рядов в одном фрейме данных?

Вот пример данных:

data<-read.table(textConnection('customer_ID transaction_num sales
                                    Josh         1              $35
                                    Josh         2              $50
                                    Josh         3              $65
                                    Ray          1              $65
                                    Ray          2              $52
                                    Ray          3              $49
                                    Eric         1              $10 
                                    Eric         2              $13
                                    Eric         3              $9'),header=TRUE,stringsAsFactors=FALSE)
    
  
  data$sales<-as.numeric(sub('\\$','',data$sales))

Понятно, как получить значения тренда для одного из идентификаторов клиентов:

  dataTransformed<-dcast(data, transaction_num ~ customer_ID, value.var="sales", fun.aggregate=sum)
  transaction_num Eric Josh Ray
               1   10   35  65
               2   13   50  52
               3    9   65  49
  fitted(lm(dataTransformed$Eric ~ dataTransformed$transaction_num))
    1        2        3 
11.16667 10.66667 10.16667 

Но я хочу получить фрейм данных со столбцом «значения тренда» для каждого идентификатора клиента вместо столбца «продажи» или просто рядом с ним. Чтобы получить что-то вроде этого:

                                   customer_ID transaction_num trend 
                                    Josh         1              35
                                    Josh         2              50
                                    Josh         3              65
                                    Ray          1              63.3
                                    Ray          2              10.6
                                    Ray          3              10.2
                                    Eric         1              11.2 
                                    Eric         2              10.7
                                    Eric         3              10.2

Любая помощь будет признательна. Спасибо


person Maksym Moroz    schedule 31.08.2020    source источник


Ответы (2)


Вы можете просто сделать lm с термином взаимодействия:

data$trend <- fitted(lm(sales ~ customer_ID * transaction_num, data))
data
#>   customer_ID transaction_num sales    trend
#> 1        Josh               1    35 35.00000
#> 2        Josh               2    50 50.00000
#> 3        Josh               3    65 65.00000
#> 4         Ray               1    65 63.33333
#> 5         Ray               2    52 55.33333
#> 6         Ray               3    49 47.33333
#> 7        Eric               1    10 11.16667
#> 8        Eric               2    13 10.66667
#> 9        Eric               3     9 10.16667
person Allan Cameron    schedule 31.08.2020

Вы можете применить lm для каждого customer_ID.

library(dplyr)

data %>% 
    group_by(customer_ID) %>% 
    mutate(trend = fitted(lm(sales ~ transaction_num)))

#  customer_ID transaction_num sales trend
#  <chr>                 <int> <dbl> <dbl>
#1 Josh                      1    35  35  
#2 Josh                      2    50  50. 
#3 Josh                      3    65  65  
#4 Ray                       1    65  63.3
#5 Ray                       2    52  55.3
#6 Ray                       3    49  47.3
#7 Eric                      1    10  11.2
#8 Eric                      2    13  10.7
#9 Eric                      3     9  10.2
person Ronak Shah    schedule 31.08.2020
comment
Разве это не то же самое, что поместить термин взаимодействия в lm? - person Allan Cameron; 31.08.2020
comment
Ох.. это? Я не знаю об этом. - person Ronak Shah; 31.08.2020
comment
Я так думаю: использование оператора * в формуле означает, что мы делаем ANCOVA, поэтому он позволит рассчитать отрезок и общий наклон регрессии, а также индивидуальные наклоны регрессии для каждого клиента. В любом случае это выглядит как один и тот же результат (+/- ошибки округления). В любом случае, ваше решение по-прежнему правильное и аккуратное! - person Allan Cameron; 31.08.2020