Calcular el NPS con media móvil
En ocasiones resulta interesante ir analizando la evolución de los KPIs de la empresa de forma periódica. Esto cobra suma importancia cuando se introducen cambios en la forma de proceder, en los protocolos de prestación del servicio que se está valorando. Nuevamente recurrimos a nuestra empresa ficticia NeoEliaValls, de la que disponemos los siguientes datos …
head(data[,1:7],20)
## IDNUM DTCALL TMCALL MOTIVATION CALLCENTER VALORCALL NPS
## 1 1 2017-09-29 8:38:24 2 1 10 100
## 2 2 2017-09-29 8:52:48 1 1 2 -100
## 3 3 2017-09-29 10:19:12 2 1 5 -100
## 4 4 2017-09-29 11:31:12 2 1 1 -100
## 5 5 2017-09-29 12:00:00 1 2 4 -100
## 6 6 2017-09-29 12:00:00 3 2 5 -100
## 7 7 2017-09-29 12:28:48 2 1 5 -100
## 8 8 2017-09-29 15:21:36 2 1 5 -100
## 9 9 2017-09-29 16:48:00 1 2 5 -100
## 10 10 2017-09-29 16:48:00 1 2 0 -100
## 11 11 2017-09-30 8:24:00 2 1 10 100
## 12 12 2017-09-30 11:02:24 2 1 7 0
## 13 13 2017-09-30 12:28:48 3 1 4 -100
## 14 14 2017-09-30 12:43:12 3 2 0 -100
## 15 15 2017-09-30 15:50:24 3 2 0 -100
## 16 16 2017-09-30 17:16:48 2 2 1 -100
## 17 17 2017-10-01 8:52:48 1 2 8 0
## 18 18 2017-10-01 10:19:12 2 1 3 -100
## 19 19 2017-10-01 13:40:48 2 1 5 -100
## 20 20 2017-10-01 14:09:36 2 1 3 -100
Podemos observar que en esta muestra de 20 registros (los 20 primeros de 6441 llamadas ) las llamadas se van produciendo a lo largo de los días. Si al analizar el KPI vemos que algo no anda bien, y establecemos cambios de protocolo, y queremos seguir analizando la evolución del indicador, la mejor forma de hacerlo es utilizando no la media aritmética que nos daría un dato agregado del período de trabajo, sino la media móvil seleccionando el nº de llamadas (primero) o días (después) que fueran necesarios.
En el siguiente script utilizamos la función rollmean
del paquete zoo
que nos permite calcular la media móvil con un agregado de k registros, en nuestro caso k = 100
por tanto, las últimas 100 llamadas.
data <- data %>%
select(1:7) %>% # usa solo las variables de 1 a 7
mutate(NPSMOV=round(rollmean(NPS, k = 100 , fill = NA, align = "right"),2)) # calcula
head(data[90:110, ],20)
## IDNUM DTCALL TMCALL MOTIVATION CALLCENTER VALORCALL NPS NPSMOV
## 90 90 2017-10-11 14:24:00 1 1 10 100 NA
## 91 91 2017-10-11 14:24:00 3 2 10 100 NA
## 92 92 2017-10-11 16:48:00 1 1 4 -100 NA
## 93 93 2017-10-12 8:38:24 3 2 7 0 NA
## 94 94 2017-10-12 9:07:12 3 2 4 -100 NA
## 95 95 2017-10-12 10:04:48 3 2 4 -100 NA
## 96 96 2017-10-12 10:33:36 2 2 4 -100 NA
## 97 97 2017-10-12 11:16:48 2 1 7 0 NA
## 98 98 2017-10-12 12:28:48 2 2 6 -100 NA
## 99 99 2017-10-12 12:43:12 1 2 3 -100 NA
## 100 100 2017-10-12 13:26:24 2 1 0 -100 -48
## 101 101 2017-10-12 14:24:00 2 1 4 -100 -50
## 102 102 2017-10-12 14:52:48 2 2 0 -100 -50
## 103 103 2017-10-12 16:33:36 2 2 4 -100 -50
## 104 104 2017-10-12 17:02:24 2 1 6 -100 -50
## 105 105 2017-10-13 8:52:48 1 2 3 -100 -50
## 106 106 2017-10-13 10:33:36 1 2 2 -100 -50
## 107 107 2017-10-13 12:28:48 2 1 5 -100 -50
## 108 108 2017-10-13 12:43:12 2 1 1 -100 -50
## 109 109 2017-10-13 12:57:36 1 2 2 -100 -50
¿Son correctos los datos? lo son, pero nótese que hay dos variables que tienen incidencia sobre este cálculo, que por hacerlo fácil no hemos contemplado, la motivación de la llamada (consulta=1, reclamación =2, sugerencia=3) y otra que es el call-center que atiende la llamada.
También, nótese que en el script, se están mostrando los registros del 90 al 110, ¿por qué? porque los 100 primeros registros no calculan el nps móvil ya que no hay suficientes casos anteriores (100) para ser posible su cómputo.
Vamos pues a tener en cuenta los campos motivación y call center. Para ello calcularemos
data11 <- data %>%
filter(MOTIVATION==1 & CALLCENTER==1) %>% # elige valores 1 en ambas variables
select(1:7) %>% # usa solo las variables de 1 a 7
mutate(NPSMOV=round(rollmean(NPS, k = 100 , fill = NA, align = "right"),2)) # calcula
head(data11[90:110, ],20)
## IDNUM DTCALL TMCALL MOTIVATION CALLCENTER VALORCALL NPS NPSMOV
## 90 493 2017-12-07 11:31:12 1 1 0 -100 NA
## 91 499 2017-12-07 17:02:24 1 1 3 -100 NA
## 92 501 2017-12-07 17:45:36 1 1 0 -100 NA
## 93 508 2017-12-09 8:52:48 1 1 8 0 NA
## 94 514 2017-12-09 15:07:12 1 1 6 -100 NA
## 95 515 2017-12-09 16:19:12 1 1 2 -100 NA
## 96 518 2017-12-10 11:45:36 1 1 9 100 NA
## 97 532 2017-12-11 16:04:48 1 1 4 -100 NA
## 98 533 2017-12-12 9:07:12 1 1 5 -100 NA
## 99 539 2017-12-13 9:07:12 1 1 1 -100 NA
## 100 546 2017-12-14 10:33:36 1 1 3 -100 -47
## 101 548 2017-12-14 11:31:12 1 1 8 0 -46
## 102 561 2017-12-16 8:09:36 1 1 9 100 -44
## 103 589 2017-12-20 17:02:24 1 1 6 -100 -44
## 104 592 2017-12-21 14:09:36 1 1 10 100 -42
## 105 593 2017-12-21 14:24:00 1 1 2 -100 -42
## 106 600 2017-12-22 11:45:36 1 1 0 -100 -44
## 107 608 2017-12-23 10:33:36 1 1 8 0 -43
## 108 611 2017-12-23 14:09:36 1 1 9 100 -41
## 109 614 2017-12-23 16:04:48 1 1 1 -100 -41
remove(data)
La estructura de la tabla es la misma, pero nótese que ahora las columnas de motivación y de call center tienen ambas valor 1. Para no ser muy reiterativos, dejamos para ti el cálculo de las combinaciones de motivacion (2 tipos más) y call center(1 centro más) y resto de posibles casos.
Presentamos ahora la evolución del NPSmóvil en un gráfico. Para ello utilizaremos highcharteR
como paquete de gráficos, aunque también plotly
nos daría una vista óptima.
# hacemos la tabla y la guardamos en el objeto tab
tab <- data11 %>%
tab_subgroup(NPSMOV>=0 | NPSMOV<0) %>%
tab_rows('|'= DTCALL) %>%
tab_cells('|'= unvr(NPSMOV)) %>%
tab_stat_mean(label ='|') %>%
tab_pivot(stat_position='inside_columns')
# renombramos las columnas
colnames(tab) <- c('date', 'npsmov')
#damos formato de fecha alo que será el eje x (opcional)
tab$dt <- as.Date(tab$date, format = "%Y-%m-%d")
#hacemos el gráfico
hchart(tab, 'line', hcaes(x=date, y=npsmov))
Y el mismo dato pero del último mes …
data11 <- data11 %>% filter(DTCALL > (max(DTCALL)-30))
tab <- data11 %>%
tab_subgroup(NPSMOV>=0 | NPSMOV<0) %>%
tab_rows('|'= DTCALL) %>%
tab_cells('|'= unvr(NPSMOV)) %>%
tab_stat_mean(label ='|') %>%
tab_pivot(stat_position='inside_columns')
colnames(tab) <- c('date', 'npsmov')
tab$dt <- as.Date(tab$date, format = "%Y-%m-%d")
hchart(tab, 'line', hcaes(x=date, y=npsmov), color='#eb6909')
En esos 30 últimos días nos encontramos que el último NPS nos indica las siguientes categorías:
#recodificamos la variable
data11$VALOR <- recode(data11$VALORCALL, 'detractores' = 0:6 ~1, 'neutrales' = 7:8 ~2, 'promotores' = 9:10 ~ 3)
#obtenemos la tabla con los datos y la guardamos en tab
tab <- data11 %>%
tab_subgroup(NPSMOV>=0 | NPSMOV<0) %>%
tab_cells('|'= unvr(VALOR)) %>%
tab_stat_cpct(label ='|', total_row_position = 'none') %>%
tab_pivot(stat_position='inside_columns')
# mostramos la tabla
tab
#Total | |
---|---|
detractores | 69.8 |
neutrales | 16.3 |
promotores | 14.0 |
#renombramos las columnas de la tabla
colnames(tab) <- c('nps', 'pct')
#hacemos el gráfico
hchart(tab, 'bar', hcaes(x=nps, y=round(tab$pct,2)), colorByPoint=TRUE) %>%
hc_colors(color = c('red', 'orange','green')) %>%
hc_yAxis(title=list(text='Valor NPS'))
La media de los 100 últimos NPS calculados (recordemos que se calculan llamada a llamada) es …
meannpsmov <- round(mean(data11$NPSMOV, na.rm=TRUE),2)
gauge(value=meannpsmov,min=-100,max=100,label = 'Nps', abbreviate = TRUE, abbreviateDecimals = 1)
Y hasta aquí el proceso. Haciendo resumen:
- hemos cargado un archivo de SPSS etiquetado
- hemos calculado un NPS móvil con los últimos 100 registros de una combinación de valores
- hemos mostrado el peso de cada categoría del NPS en el conjunto
- hemos calculado un indicador del NPS, representado por un
gauge
Hasta la próxima !!!