Cyclistic es una empresa de bicicletlas compartidas en chicago, la cual quiere maximizar la cantidad de membresías anuales, por lo tanto, debemos de encontrar las diferencias que existen entre los cyclistas anuales y los ocasionales para diseñar una estrategía de marketing.
Nuestra tarea es descubrir en qué se diferencian los cyclistas socios anuales y los ciclistas ocasionales con respecto al uso de las bicicletas de cyclistic.
¿En qué se diferencian los socios anuales y los ciclistas ocasionales con respecto al uso de las bicicletas de Cyclistic?
Tenemos un conjunto de datos de los últimos 12 meses de viajes de cyclistic, los vamos a limpiar y tranformar.
Cargamos las librerías necesarias.
Vamos a cargar los datos de los 12 meses y los unimos en un solo conjunto de datos:
enero <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\enero2022.csv")
febrero <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\febrero2022.csv")
marzo <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\marzo2022.csv")
abril <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\abril2022.csv")
mayo <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\mayo2022.csv")
junio <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\junio2022.csv")
julio <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\julio2022.csv")
agosto <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\agosto2022.csv")
sept2021 <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\septiembre2021.csv")
oct2021 <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\octubre2021.csv")
nov2021 <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\noviembre2021.csv")
dic2021 <- read.csv("D:\\Desktop\\CursoAD\\Caso_Practico_1_Archivos\\2021-2022\\diciembre2021.csv")
c_1 <- rbind(enero,febrero,marzo,abril,mayo,junio,julio,agosto,sept2021,oct2021,nov2021,dic2021)
Observamos el conjunto:
summary(c_1)
## ride_id rideable_type started_at ended_at
## Length:5883043 Length:5883043 Length:5883043 Length:5883043
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## start_station_name start_station_id end_station_name end_station_id
## Length:5883043 Length:5883043 Length:5883043 Length:5883043
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## start_lat start_lng end_lat end_lng
## Min. :41.64 Min. :-87.84 Min. :41.39 Min. :-88.97
## 1st Qu.:41.88 1st Qu.:-87.66 1st Qu.:41.88 1st Qu.:-87.66
## Median :41.90 Median :-87.64 Median :41.90 Median :-87.64
## Mean :41.90 Mean :-87.65 Mean :41.90 Mean :-87.65
## 3rd Qu.:41.93 3rd Qu.:-87.63 3rd Qu.:41.93 3rd Qu.:-87.63
## Max. :45.64 Max. :-73.80 Max. :42.37 Max. :-87.50
## NA's :5727 NA's :5727
## member_casual
## Length:5883043
## Class :character
## Mode :character
##
##
##
##
colnames(c_1)
## [1] "ride_id" "rideable_type" "started_at"
## [4] "ended_at" "start_station_name" "start_station_id"
## [7] "end_station_name" "end_station_id" "start_lat"
## [10] "start_lng" "end_lat" "end_lng"
## [13] "member_casual"
str(c_1)
## 'data.frame': 5883043 obs. of 13 variables:
## $ ride_id : chr "C2F7DD78E82EC875" "A6CF8980A652D272" "BD0F91DFF741C66D" "CBB80ED419105406" ...
## $ rideable_type : chr "electric_bike" "electric_bike" "classic_bike" "classic_bike" ...
## $ started_at : chr "2022-01-13 11:59:47" "2022-01-10 08:41:56" "2022-01-25 04:53:40" "2022-01-04 00:18:04" ...
## $ ended_at : chr "2022-01-13 12:02:44" "2022-01-10 08:46:17" "2022-01-25 04:58:01" "2022-01-04 00:33:00" ...
## $ start_station_name: chr "Glenwood Ave & Touhy Ave" "Glenwood Ave & Touhy Ave" "Sheffield Ave & Fullerton Ave" "Clark St & Bryn Mawr Ave" ...
## $ start_station_id : chr "525" "525" "TA1306000016" "KA1504000151" ...
## $ end_station_name : chr "Clark St & Touhy Ave" "Clark St & Touhy Ave" "Greenview Ave & Fullerton Ave" "Paulina St & Montrose Ave" ...
## $ end_station_id : chr "RP-007" "RP-007" "TA1307000001" "TA1309000021" ...
## $ start_lat : num 42 42 41.9 42 41.9 ...
## $ start_lng : num -87.7 -87.7 -87.7 -87.7 -87.6 ...
## $ end_lat : num 42 42 41.9 42 41.9 ...
## $ end_lng : num -87.7 -87.7 -87.7 -87.7 -87.6 ...
## $ member_casual : chr "casual" "casual" "member" "casual" ...
vista <- head(c_1)
vista
## ride_id rideable_type started_at ended_at
## 1 C2F7DD78E82EC875 electric_bike 2022-01-13 11:59:47 2022-01-13 12:02:44
## 2 A6CF8980A652D272 electric_bike 2022-01-10 08:41:56 2022-01-10 08:46:17
## 3 BD0F91DFF741C66D classic_bike 2022-01-25 04:53:40 2022-01-25 04:58:01
## 4 CBB80ED419105406 classic_bike 2022-01-04 00:18:04 2022-01-04 00:33:00
## 5 DDC963BFDDA51EEA classic_bike 2022-01-20 01:31:10 2022-01-20 01:37:12
## 6 A39C6F6CC0586C0B classic_bike 2022-01-11 18:48:09 2022-01-11 18:51:31
## start_station_name start_station_id end_station_name
## 1 Glenwood Ave & Touhy Ave 525 Clark St & Touhy Ave
## 2 Glenwood Ave & Touhy Ave 525 Clark St & Touhy Ave
## 3 Sheffield Ave & Fullerton Ave TA1306000016 Greenview Ave & Fullerton Ave
## 4 Clark St & Bryn Mawr Ave KA1504000151 Paulina St & Montrose Ave
## 5 Michigan Ave & Jackson Blvd TA1309000002 State St & Randolph St
## 6 Wood St & Chicago Ave 637 Honore St & Division St
## end_station_id start_lat start_lng end_lat end_lng member_casual
## 1 RP-007 42.01280 -87.66591 42.01256 -87.67437 casual
## 2 RP-007 42.01276 -87.66597 42.01256 -87.67437 casual
## 3 TA1307000001 41.92560 -87.65371 41.92533 -87.66580 member
## 4 TA1309000021 41.98359 -87.66915 41.96151 -87.67139 casual
## 5 TA1305000029 41.87785 -87.62408 41.88462 -87.62783 member
## 6 TA1305000034 41.89563 -87.67207 41.90312 -87.67394 member
Buscamos y exploramos valores nulos:
any(is.na(c_1))
## [1] TRUE
apply(is.na(c_1), 2, sum)
## ride_id rideable_type started_at ended_at
## 0 0 0 0
## start_station_name start_station_id end_station_name end_station_id
## 0 0 0 0
## start_lat start_lng end_lat end_lng
## 0 0 5727 5727
## member_casual
## 0
Observamos que las columnas end_lat y end_Ing son las que contienen los valores nulos, al ser un conjunto de datos ficticio, queda a mi criterio eliminarlos o no.
Eliminamos los valores nulos:
c_2 <- na.omit(c_1)#Eliminé 5,727
sum(is.na(c_2))
## [1] 0
Observamos que el valor de valores na es 0.
Borramos las columnas que considero no necesito para el análisis por ahora:
c_3 <- c_2 %>%
select(-c(start_lat, start_lng, end_lat, end_lng))
Cambiamos las columnas started_at y ended_at a formato ymd_hms:
col_started <- ymd_hms(c_3$started_at)
col_ended <- ymd_hms(c_3$ended_at)
#quitamos las columnas con el formato chr
c_4 <- select(c_3, -ended_at, -started_at)
#agregamos las columnas con el formato ymd:hms al conjunto de datos
c_5 <- c_4 %>% mutate(started_at = col_started)%>%
mutate(ended_at = col_ended)
c_5[1:5,8:9]
## started_at ended_at
## 1 2022-01-13 11:59:47 2022-01-13 12:02:44
## 2 2022-01-10 08:41:56 2022-01-10 08:46:17
## 3 2022-01-25 04:53:40 2022-01-25 04:58:01
## 4 2022-01-04 00:18:04 2022-01-04 00:33:00
## 5 2022-01-20 01:31:10 2022-01-20 01:37:12
Creamos la columna “duración viaje” restando a started_at, ended_at. Se crea en segundos pero para fines visuales, también creamos una en formato hms:
c_6 <- c_5 %>% mutate(duracion_viaje_secs = ended_at - started_at)
c_7 <- c_6 %>% mutate(duracion_viaje = as.hms(ended_at - started_at))
c_7[1:5,9:11]
## ended_at duracion_viaje_secs duracion_viaje
## 1 2022-01-13 12:02:44 177 secs 00:02:57
## 2 2022-01-10 08:46:17 261 secs 00:04:21
## 3 2022-01-25 04:58:01 261 secs 00:04:21
## 4 2022-01-04 00:33:00 896 secs 00:14:56
## 5 2022-01-20 01:37:12 362 secs 00:06:02
Creamos una columna con los días de la semana de los viajes, empezando 1 en domingo y 7 sábado. De igual manera creamos una en formato chr:
c_8 <- c_7 %>% mutate(dia_semana = (as.POSIXlt(c_5$started_at)$wday+1)) %>%
mutate(dia = (weekdays(c_5$started_at)))
c_8[1:5,10:13]
## duracion_viaje_secs duracion_viaje dia_semana dia
## 1 177 secs 00:02:57 5 jueves
## 2 261 secs 00:04:21 2 lunes
## 3 261 secs 00:04:21 3 martes
## 4 896 secs 00:14:56 3 martes
## 5 362 secs 00:06:02 5 jueves
Creamos una columna para extraer los meses de los viajes:
c_9 <- c_8%>%
mutate(mes_letra = format(c_6$started_at, "%B"))
c_9[1:5,11:14]
## duracion_viaje dia_semana dia mes_letra
## 1 00:02:57 5 jueves enero
## 2 00:04:21 2 lunes enero
## 3 00:04:21 3 martes enero
## 4 00:14:56 3 martes enero
## 5 00:06:02 5 jueves enero
Creamos una columna para la temporada de los viajes de acuerdo al mes:
c_10 <- c_9 %>%
mutate(temporada = case_when(
(mes_letra == "diciembre") | (mes_letra == "enero")~ "invierno",
(mes_letra == "marzo") | (mes_letra == "abril") ~ "primavera",
(mes_letra == "junio") | (mes_letra == "julio") ~ "verano",
(mes_letra == "febrero") ~ "invierno",
(mes_letra == "mayo") ~ "primavera",
(mes_letra == "agosto") ~ "verano",
(mes_letra == "noviembre") ~ "otoño",
(mes_letra == "septiembre") | (mes_letra == "octubre") ~ "otoño"))
c_10[1:5,13:15]
## dia mes_letra temporada
## 1 jueves enero invierno
## 2 lunes enero invierno
## 3 martes enero invierno
## 4 martes enero invierno
## 5 jueves enero invierno
Revisamos que todos los meses sean proporcionales a la cantidad de variables;
length(c_10$temporada [c_10$temporada == "primavera"])
## [1] 1288844
length(c_10$temporada [c_10$temporada == "verano"])
## [1] 2375779
length(c_10$temporada [c_10$temporada == "otoño"])
## [1] 1746081
length(c_10$temporada [c_10$temporada == "invierno"])
## [1] 466612
Comparamos a los miembros anuales con los ciclistas ocasionales:
aggregate(c_10$duracion_viaje ~ c_10$member_casual, FUN = mean)
## c_10$member_casual c_10$duracion_viaje
## 1 casual 1425.9661 secs
## 2 member 755.3348 secs
aggregate(c_10$duracion_viaje ~ c_10$member_casual, FUN = median)
## c_10$member_casual c_10$duracion_viaje
## 1 casual 00:13:53
## 2 member 00:08:58
aggregate(c_10$duracion_viaje ~ c_10$member_casual, FUN = max)
## c_10$member_casual c_10$duracion_viaje
## 1 casual 2442301 secs
## 2 member 89996 secs
aggregate(c_10$duracion_viaje ~ c_10$member_casual, FUN = min)
## c_10$member_casual c_10$duracion_viaje
## 1 casual -8245 secs
## 2 member -7745 secs
Nos damos cuenta que hay viajes en negativo, decidimos eliminarlos
Eliminar viajes con valores negativos:
cyclistic <- c_10[!(c_10$start_station_name == "HQ QR" | c_10$duracion_viaje_secs<0),]
Media duración de los viajes:
as.hms(mean(cyclistic$duracion_viaje_secs))
## 00:17:16.489844
mean(cyclistic$duracion_viaje)
## Time difference of 1036.49 secs
Observamos las modas:
mfv(cyclistic$dia)
## [1] "sábado"
mfv(cyclistic$mes_letra)
## [1] "julio"
mfv(cyclistic$temporada)
## [1] "verano"
Cálculamos el promedio de duración de viaje por tipo de ciclistas:
aggregate(cyclistic$duracion_viaje_secs~member_casual,cyclistic, mean,na.rm=TRUE)
## member_casual cyclistic$duracion_viaje_secs
## 1 casual 1426.0544 secs
## 2 member 755.3726 secs
Nos damos cuenta que hay ciclistas con viajes de 0 segundos, los cuales también eliminamos:
cyclisticV2 <- cyclistic[!(cyclistic$duracion_viaje_secs<=0),]
Tiempo de viaje promedio por día por cada tipo de ciclista:
aggregate(cyclisticV2$duracion_viaje ~ cyclisticV2$member_casual + cyclisticV2$dia, FUN = mean)
## cyclisticV2$member_casual cyclisticV2$dia cyclisticV2$duracion_viaje
## 1 casual domingo 1655.0035 secs
## 2 member domingo 842.7542 secs
## 3 casual jueves 1266.2252 secs
## 4 member jueves 726.2407 secs
## 5 casual lunes 1470.4409 secs
## 6 member lunes 733.0142 secs
## 7 casual martes 1247.5052 secs
## 8 member martes 715.3362 secs
## 9 casual miércoles 1226.3644 secs
## 10 member miércoles 719.5006 secs
## 11 casual sábado 1580.2663 secs
## 12 member sábado 841.0429 secs
## 13 casual viernes 1329.5970 secs
## 14 member viernes 740.4586 secs
Número de viajes por día y promedio de duración:
La imagen nos muestra que los ciclistas ocasionales prefieren los fines de semana para realiza sus viajes. Los ciclistas miembros prefieren los viajes entre semana y en promedio son viajes cortos a comparación de los ciclistas ocasionales que suelen realizar viajes más largos.
Promedio de duración de viaje por días de la semana
Los usuarios casuales en promedio realizan viajes más largos que los miembros anuales. El pico de viajes se encuentra entre sábado y domingo, siendo estos viajes realizados en su mayoría por usuarios ocasionales.
Número de viajes por meses y promedio de duración del viaje
Los viajes de ciclistas ocasionales aumentan en junio y julio, mientras tanto julio y agosto son los meses preferidos por los ciclistas miembros.
Tipo de bicicleta preferida por los ciclistas:
La bicicleta eléctrica es la preferica por los ciclistas casuales, mientras que la bicicleta clásica es elegida más por los miembros ciclistas.
Temporada favorita por los ciclistas:
Gráfica 5: Temporada
Los dos tipos de ciclistas prefieren los veranos para realizar sus viajes y reducen su cantidad de viajes considerablemente en invierno
Tres recomendaciones que pude observar a partir del comportamiento de los datos:
Lanzar la campaña de marketing para usuarios casuales empezando la temporada de verano, que abarca los meses julio, julio y agosto, así como en los días sábado y domingo.
Enfatizar la campaña de marketing en el uso de la bicicleta eléctrica qué es la preferida por los ciclistas casuales.
Agregar promociones para los miembros anuales que viajen más de 15 minutos, ya que los usuarios casuales suelen realizar viajes más largos a partir de los minutos ya mencionados y puede interesarles la membresía anual al contar con esa promoción.
Conjuntos de datos abiertos, bajo la licencia Motivate, almacenados en: https://divvy-tripdata.s3.amazonaws.com/index.html
Mariana Raquel Flores Carrillo ir a linkedin: https://www.linkedin.com/in/mariana-raquel-flores-carrillo-20201b247/