RESUMEN DE LA EMPRESA

Cyclistic, es una empresa ficticia, dedica al servicio de bicicletas compartidas en la mayoria de estaciones de la ciudad de Chicago, durante algunos años su trayectora ha tenido exito, con las bicicletas compartidas, las mismas que estan equipadas con geolocalizadores y sistema de desbloqueo en cada estacion.

Su declaracion de empresa, se basa en crear conciencia general del uso de bicicleta compartidas, atrayendo un gran segmento de consumidores. Un enfoque que hace posible, que sus planes de precios sean adecuados, existe membresias anuales, que permite ser miembro anual de Cyclistic y otro para ciclista ocasional por dia.

Parte de la estrategia, ha sido el uso efectivo de redes sociales. Su Gerente y Directora de Marketing, esta comprometida en desarrollar campaña, para impulsar a los clientes ocasionales en miembros anuales. Para cerciorarse, ha encargado a su equipo de analistas de datos, buscar un paramentro o tendencia sobre los datos que proporciona la empresa Motivate International Inc. quien ha puesto a disposición los datos bajo esta licencia, son datos publicos.

PREGUNTAS

En este apartado se incluiye cuenstionario sobre el caso de estudio, el cual hay que responder, que es parte de Coursera en el programa de Google para Certificacion de Analista de Datos Junior.

1. ¿En qué se diferencian los usuarios anuales y los ciclistas ocasionales al usar las bicicletas de Cyclistic?

Los clientes que compran pases de un solo viaje o de un día completo se conocen como ciclistas ocasionales. Los clientes que adquieren membresías anuales son miembros de Cyclistic.

2. ¿Por qué los ciclistas ocasionales comprarían membresías anuales de Cyclistic?

Su flexibilidad de precios ayuda a Cyclistic a atraer más clientes, Moreno cree que maximizar el número de miembros anuales será clave para el crecimiento futuro.

3. ¿Cómo puede Cyclistic usar los medios digitales para influenciar a los ciclistas ocasionales para que se conviertan en miembros?

Lily Moreno: La directora de marketing y su gerente. Moreno es responsable del desarrollo de campañas e iniciativas para promover el programa de bicicletas compartidas. Estas pueden incluir correo electrónico, redes sociales y otros canales.

La estrategia de marketing de Cyclistic se basó en crear conciencia general y atraer a amplios segmentos de consumidores. Un enfoque que ayudó a hacer posibles estas cosas fue la flexibilidad de sus planes de precios: pases de un solo viaje, pases de un día completo y membresías anuales. Los clientes que compran pases de un solo viaje o de un día completo se conocen como ciclistas ocasionales. Los clientes que adquieren membresías anuales son miembros de Cyclistic.

4. Moreno te ha asignado la primera pregunta para responder: ¿Cómo usan las bicicletas Cyclistic los miembros anuales y los ciclistas ocasionales de manera diferente?

Cyclistic se distingue al ofrecer también bicicletas reclinables, triciclos de mano y bicicletas de carga, lo que hace que las bicicletas compartidas sean más inclusivas para las personas con discapacidades y los ciclistas que no pueden usar una bicicleta estándar de dos ruedas. La mayoría de los ciclistas optan por las bicicletas tradicionales; alrededor del 8% de los ciclistas usan las opciones de asistencia. Los usuarios de Cyclistic son más propensos a montar en bicicleta por ocio, pero alrededor del 30% usa las bicicletas para viajar al trabajo todos los días.

Cyclistic lanzó una exitosa oferta de bicicletas compartidas. Desde entonces, el programa ha crecido a una flota de 5,824 bicicletas que están geolocalizadas y bloqueadas en una red de 692 estaciones en Chicago.Aproximadamente un promedio de 8 bicicletas por estación. Las bicicletas se pueden desbloquear en una estación y devolver a cualquier otra estación en el sistema en cualquier momento.

5. Una declaración clara de la tarea comercial

Cyclistic es un programa con un equipo que trabaja para generar conciencia del uso de bicicletas compartidas, sirviendo fielmente a cada uno de sus clientes.

6. Una descripción de todas las fuentes de datos utilizadas

La utilización de datos históricos de viajes de Cyclistic para analizar se realizó la descarga de los datos de viajes de los clientes de Cyclistic datos Divvy_2019_Q1 y Divvy_2020_Q1 . Los mismo que viene en formato .csv (Valores separados por coma). La empresa Motivate International Inc. es propietaria bajo licencia, estos datos son de exploración para fines de estudio.

7. ¿Cuál es el problema que estás tratando de resolver?

¿Por qué los ciclistas ocasionales comprarían membresías anuales de Cyclistic?

8. ¿Cómo pueden tus conocimientos impulsar las decisiones comerciales?

Dando valor a los datos como Analista de Datos para descubrir tendencias o parámetros, que sea relevante e importante para la toma de decisiones, de acuerdo a la información proporcionada.

9. ¿Dónde se encuentran sus datos?

Los datos fueron descargados de Coursera en formato .csv son 2 archivos Divvy_Trips_2019_Q1.csv y Divvy_Trips_2020_Q1.CSV los cuales se encuentran descargado y archivados en google drive y google sheet personal, en Google Drive también están respaldados los originales en .csv

10. ¿Cómo están organizados los datos?

Cada archivo está organizado por columnas iniciando con una columnas identificadoras, y por filas en un formato que esta determinado, sin embargo su cantidad de columnas entre las dos archivos difiere la Divvy_Trips_2019_Q1 tiene 12 columnas mientras que Divvy_Trips_2020_Q1 contiene 13 columnas, ambas son estructurada.Ambas tablas tiene formatos: cualitativos ; cuantitativos ; discretos, continuos, fraccionados.

11. ¿Hay problemas de sesgo o credibilidad en estos datos? ¿Sus datos ROCCC?

Con la observación de datos, confirman que no está completo algunas celdas de las columnas, se presentan como vacías.

Considero que en la credibilidad de los datos, existen algunas incoherencias en algunos registros por Ejemplo: el uso de la bicicleta por dos segundos.

A pesar de que viene de una fuente de datos de primer instancia , su información es considerada como confiable, actual percibiendo errores humanos o de programa.

12. ¿Cómo está abordando las licencias, la privacidad, la seguridad y la accesibilidad?

Los conjuntos de datos tienen un nombre diferente porque Cyclistic es una empresa ficticia. Para los fines de este estudio de caso, los conjuntos de datos son apropiados y le permitirán responder a las preguntas comerciales. Motivate International Inc. ha puesto a disposición los datos bajo esta licencia).

Estos son datos públicos que puede utilizar para explorar cómo los diferentes tipos de clientes utilizan las bicicletas Cyclistic. Los problemas de privacidad de los datos le prohíben utilizar la información de identificación personal de los ciclistas. Esto significa que no podrá conectar las compras de pases con los números de tarjetas de crédito para determinar si los ciclistas ocasionales viven en el área de servicio de Cyclistic o si han comprado varios pases individuales.

13. ¿Cómo verificó la integridad de los datos?

Encontrar en las tablas la existencia de errores, inconsistencia en dos datos o falta de datos, es la primera visualización.

14. ¿Cómo le ayuda a responder su pregunta?

A pesar de que los datos tengan licencia y al mismo tiempo errores e inconsistencia en los datos, considero que hay aún datos significativos que permiten determinar una tendencia para analizar y que genere valor a la toma de decisiones para responde a la tarea de la empresa por medio de datos.

15. ¿Hay algún problema con los datos?

listado: A. Archivos tiene diferentes encabezados o títulos de columnas diferentes B. Cada archivo está generado sus columnas con distinto argumento, al igual que sus registros. C. Inconsistencia en los registros por ejemplo el uso de bicicleta por cuatros segundos D. Celdas vacías E.número de columnas varía por archivo. F. Formatos diferentes

16. ¿Qué herramientas está eligiendo y por qué?

Para este proyecto, he recurrido al uso de Google Sheets, Documents.herramientas que estan en la nube, permitiendo conocer su uso a largo del proceso, con Google Sheets he podido descargar los archivos csv respectivos, con los cuales se realizó tabla dinámica, al mismo tiempo, me permite conectarme con BigQuery, para formatear los archivos y al mismo tiempo para consolidarlos en uno solo, posterior a ello he utilizado Rstudio de escritorio y continuar con un dashboard en Tableau

17. ¿Ha asegurado la integridad de sus datos? Se normalizo las tablas de manera adecuada con el fin de poder analizar las mismas que posteriormente se consolido en uno solo archivo para poder analizar con el propósito de cumplir el objetivo de la empresa, quien proporciona los datos.

PREPARACION

La importancia de preparacion de datos, permite que buscar, la manera de tratar los propositos entregando resultado sobre el estudio del caso, lo realice varias practicas en diferentes herramientas.

USO DE GOOGLE SHEET, GOOGLE DRIVE Y CONEXION

Primero en Google Sheet, para ver como se comportaba los archivos dentro dentro de Google Sheet, posterior visualice tipo de formatos de cada columna, posterior realice modificacion de tipos de formatos y luego calculos individualemte de cada tabla, para continuar con la consolide de manera apilada mediante conexion de Google Drive Resultado Conexion

USO DE BIGQUERY

Segundo use Bigquery en el cual cargue los archivos individualmente .csv y posterior genere dentro de mi proyectos la consolidacion de los dos archivos bigQuery Consolidado

USO DE R CON RSTUDIO

Tercero el uso de R en RStudio, en el cual cargue los datos de la fuente, que proporciono Coursera, es aqui donde mas enfasis he puesto para el estudio, y lo que al igual que en otras plataformas realice un analisis individual de cada tabla, para posterior analizarlo de forma consolidada apilado a lo largo, al inicio se vera algunos cambios en las dos tablas pero por la diferencia de
informacion que tenia cada tabla realice primero la del año 2019 y posterior la tabla 2020, para luego consolidar entre tablas.

 library(purrr)
   Mi_Lib <- c("tidyverse","lubridate", "dplyr","tableone","naniar", "stringi", 
  "readr", "tidyr","ggplot2", "scales", "patchwork", "purrr" )
  purrr::walk(Mi_Lib, ~ library(.x, character.only = TRUE))
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## 
## Adjuntando el paquete: 'scales'
## 
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
## 
## 
## The following object is masked from 'package:purrr':
## 
##     discard

Descargamos del folder de descarga los archivos en la carpeta datos original pestaña File-> import datase ->From texT (readr)->browser->busca la carpeta o archivo click en import Divvy_Trips_2019_Q1

Divvy_Trips_2019_Q1 <- read_csv("C:/Users/fcham/Downloads/CYCLISTIC-2/Divvy_Trips_2019_Q1.csv")
## Rows: 365069 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (4): from_station_name, to_station_name, usertype, gender
## dbl  (5): trip_id, bikeid, from_station_id, to_station_id, birthyear
## num  (1): tripduration
## dttm (2): start_time, end_time
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Lo mismo para Divvy_Trips_2020_Q1

Divvy_Trips_2020_Q1 <- read_csv("C:/Users/fcham/Downloads/CYCLISTIC-2/Divvy_Trips_2020_Q1.csv")
## Rows: 426887 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (5): ride_id, rideable_type, start_station_name, end_station_name, memb...
## dbl  (6): start_station_id, end_station_id, start_lat, start_lng, end_lat, e...
## dttm (2): started_at, ended_at
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Visual Divvy_Trips_2019_Q1

View(Divvy_Trips_2019_Q1)

Visual Divvy_Trips_2020_Q1

View(Divvy_Trips_2020_Q1)

Luego de visualizar los conjuntos de datos veremos sus cabezerass head(), dimension dim() variables names(), y estructura str() de cada tabla. Con la funcion head() visualizamos los nombres de la variables o columnas, ademas de un pequeño resumen de la informtacion que contine cada tabla head(Divvy_Trips_2019_Q1)

Cabeceras de variables Divvy_Trips_2019_Q1

  head(Divvy_Trips_2019_Q1)

Cabeceras de variables Divvy_Trips_2020_Q1

  head(Divvy_Trips_2020_Q1)

Con la funcion dim() muestra el numero total de registros o filas y el numero de columnas o variables

Numero de registros Divvy_Trips_2019_Q1

  dim(Divvy_Trips_2019_Q1)
## [1] 365069     12

Numero de registros Divvy_Trips_2020_Q1

  dim(Divvy_Trips_2020_Q1)
## [1] 426887     13

Muestra el nombre de cada columna o variable d laa tabla

Nombres de variables Divvy_Trips_2019_Q1

   names(Divvy_Trips_2019_Q1)
##  [1] "trip_id"           "start_time"        "end_time"         
##  [4] "bikeid"            "tripduration"      "from_station_id"  
##  [7] "from_station_name" "to_station_id"     "to_station_name"  
## [10] "usertype"          "gender"            "birthyear"

Nombres de variables Divvy_Trips_2020_Q1

   names(Divvy_Trips_2020_Q1)
##  [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"

Como podemos ver que los nombres de las variables son distintas y pero hay similitud en ciertas variables o columnas, con registros sinonimos

Estructura Divvy_Trips_2019_Q1

  str(Divvy_Trips_2019_Q1)
## spc_tbl_ [365,069 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ trip_id          : num [1:365069] 21742443 21742444 21742445 21742446 21742447 ...
##  $ start_time       : POSIXct[1:365069], format: "2019-01-01 00:04:37" "2019-01-01 00:08:13" ...
##  $ end_time         : POSIXct[1:365069], format: "2019-01-01 00:11:07" "2019-01-01 00:15:34" ...
##  $ bikeid           : num [1:365069] 2167 4386 1524 252 1170 ...
##  $ tripduration     : num [1:365069] 390 441 829 1783 364 ...
##  $ from_station_id  : num [1:365069] 199 44 15 123 173 98 98 211 150 268 ...
##  $ from_station_name: chr [1:365069] "Wabash Ave & Grand Ave" "State St & Randolph St" "Racine Ave & 18th St" "California Ave & Milwaukee Ave" ...
##  $ to_station_id    : num [1:365069] 84 624 644 176 35 49 49 142 148 141 ...
##  $ to_station_name  : chr [1:365069] "Milwaukee Ave & Grand Ave" "Dearborn St & Van Buren St (*)" "Western Ave & Fillmore St (*)" "Clark St & Elm St" ...
##  $ usertype         : chr [1:365069] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ gender           : chr [1:365069] "Male" "Female" "Female" "Male" ...
##  $ birthyear        : num [1:365069] 1989 1990 1994 1993 1994 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Estructura Divvy_Trips_2020_Q1

  str(Divvy_Trips_2020_Q1)
## spc_tbl_ [426,887 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ ride_id           : chr [1:426887] "EACB19130B0CDA4A" "8FED874C809DC021" "789F3C21E472CA96" "C9A388DAC6ABF313" ...
##  $ rideable_type     : chr [1:426887] "docked_bike" "docked_bike" "docked_bike" "docked_bike" ...
##  $ started_at        : POSIXct[1:426887], format: "2020-01-21 20:06:59" "2020-01-30 14:22:39" ...
##  $ ended_at          : POSIXct[1:426887], format: "2020-01-21 20:14:30" "2020-01-30 14:26:22" ...
##  $ start_station_name: chr [1:426887] "Western Ave & Leland Ave" "Clark St & Montrose Ave" "Broadway & Belmont Ave" "Clark St & Randolph St" ...
##  $ start_station_id  : num [1:426887] 239 234 296 51 66 212 96 96 212 38 ...
##  $ end_station_name  : chr [1:426887] "Clark St & Leland Ave" "Southport Ave & Irving Park Rd" "Wilton Ave & Belmont Ave" "Fairbanks Ct & Grand Ave" ...
##  $ end_station_id    : num [1:426887] 326 318 117 24 212 96 212 212 96 100 ...
##  $ start_lat         : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ start_lng         : num [1:426887] -87.7 -87.7 -87.6 -87.6 -87.6 ...
##  $ end_lat           : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ end_lng           : num [1:426887] -87.7 -87.7 -87.7 -87.6 -87.6 ...
##  $ member_casual     : chr [1:426887] "member" "member" "member" "member" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   ride_id = col_character(),
##   ..   rideable_type = col_character(),
##   ..   started_at = col_datetime(format = ""),
##   ..   ended_at = col_datetime(format = ""),
##   ..   start_station_name = col_character(),
##   ..   start_station_id = col_double(),
##   ..   end_station_name = col_character(),
##   ..   end_station_id = col_double(),
##   ..   start_lat = col_double(),
##   ..   start_lng = col_double(),
##   ..   end_lat = col_double(),
##   ..   end_lng = col_double(),
##   ..   member_casual = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

Muestra la estructura de cada tabla este momento me encuentro en la fase para procesar los datos nuevamene llamare a mis dos tablas para prosesar

PROCESO RStudio

CREACION DE VARIABLE DENTRO DE TABLAS Divvy_Trips_2019_Q1 Y

Divvy_Trips_2020_Q1 DIFERENCIA DE TIEMPO

Creamos la columna con nombre ride_length en Divvy_Trips_2019_Q1 que contega
la diferencia de tiempo entre las columnas end_time y start_time y en la tabla Divvy_Trips_2020_Q1 se encuentra las columnas ended_at y started_at para encontrar su diferencia de tiempo, tambien con el nombre ride_length. En este caso entre las columnas usamos la funcion as.Date(), por ser formato de fecha y hora distinta clase POSIXct , lo que causaba un error al hacerlo de manera simple. Ademas permite mantener el mismo formato.

DIFERENCIA DE TIEMPO Divvy_Trips_2019_Q1

Divvy_Trips_2019_Q1$ride_length <- 
    (Divvy_Trips_2019_Q1$end_time) - 
    ( Divvy_Trips_2019_Q1$start_time)

Visual

  View(Divvy_Trips_2019_Q1)

DIFERENCIA DE TIEMPO Divvy_Trips_2020_Q1

Divvy_Trips_2020_Q1$ride_length <- 
    (Divvy_Trips_2020_Q1$ended_at) - 
    ( Divvy_Trips_2020_Q1$started_at)

Visual

  View(Divvy_Trips_2020_Q1)

CONVERTIR MINUTOS A SEGUNDOS TALBLA Divvy_Trips_2019_Q1

Para que sea coherente entre las tablas Divvy_Trips_2019_Q1 se convirtio la columna ride_length de minutos a segundo con la finalidad de tener igualdad de tiempos con la tabla Divvy_Trips_2020_Q1.

CONVERSION

Divvy_Trips_2019_Q1$ride_length <- Divvy_Trips_2019_Q1$ride_length * 60

Visual

View(Divvy_Trips_2019_Q1)  

NOMBRE DEL DIA DE LA SEMANA EN TABLAS Divvy_Trips_2019_Q1 Y Divvy_Trips_2020_Q1

Realizaremos el calculo para obtener el dia de la semana incluyendo el nombre columna llamada week_day para ello usaremos la columna de la tabla Divvy_Trips_2019_Q1 start_time, lo mismo para la tabla Divvy_Trips_2020_Q1 con columna started_at Usamos la funcion week() para obtener el nombre del dia de la semana

Dia de semana Divvy_Trips_2019_Q1

 Divvy_Trips_2019_Q1$week_day <- 
    weekdays.POSIXt(Divvy_Trips_2019_Q1$start_time)

Dia de semana Divvy_Trips_2020_Q1

 Divvy_Trips_2020_Q1$week_day <- 
    weekdays.POSIXt(Divvy_Trips_2020_Q1$started_at)

NUMERO DEL DIA DE LA SEMANA EN TABLAS Divvy_Trips_2019_Q1 Divvy_Trips_2020_Q1

Para tener un poco de coherencia entre tablas se creo en cada una de las columnas que facilitan el analisis es asi que Divvy_Trips_2019_Q1 y en Divvy_Trips_2020_Q1 se creo el nombre num_week_day para poner el numero de dia de la semana, si nos fijamos obtubo el dato de la columna start_time en la tabla Divvy_Trips_2019_Q1 y started_at de la tabla Divvy_Trips_2019_Q1,

Numero de dia de la semana Divvy_Trips_2019_Q1

Divvy_Trips_2019_Q1$num_week_day <- wday(Divvy_Trips_2019_Q1$start_time)

Numero de dia de la semana Divvy_Trips_2020_Q1

Divvy_Trips_2020_Q1$num_week_day <- wday(Divvy_Trips_2020_Q1$started_at)

VISUALIZACIN GENERAL DE TABLAS Divvy_Trips_2019_Q1 Y Divvy_Trips_2020_Q1

Posterior se verifico su estructura con str en cada una de ellas y tambien en la parte superior del Script con View()

Estructura

str(Divvy_Trips_2019_Q1)
## spc_tbl_ [365,069 × 15] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ trip_id          : num [1:365069] 21742443 21742444 21742445 21742446 21742447 ...
##  $ start_time       : POSIXct[1:365069], format: "2019-01-01 00:04:37" "2019-01-01 00:08:13" ...
##  $ end_time         : POSIXct[1:365069], format: "2019-01-01 00:11:07" "2019-01-01 00:15:34" ...
##  $ bikeid           : num [1:365069] 2167 4386 1524 252 1170 ...
##  $ tripduration     : num [1:365069] 390 441 829 1783 364 ...
##  $ from_station_id  : num [1:365069] 199 44 15 123 173 98 98 211 150 268 ...
##  $ from_station_name: chr [1:365069] "Wabash Ave & Grand Ave" "State St & Randolph St" "Racine Ave & 18th St" "California Ave & Milwaukee Ave" ...
##  $ to_station_id    : num [1:365069] 84 624 644 176 35 49 49 142 148 141 ...
##  $ to_station_name  : chr [1:365069] "Milwaukee Ave & Grand Ave" "Dearborn St & Van Buren St (*)" "Western Ave & Fillmore St (*)" "Clark St & Elm St" ...
##  $ usertype         : chr [1:365069] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ gender           : chr [1:365069] "Male" "Female" "Female" "Male" ...
##  $ birthyear        : num [1:365069] 1989 1990 1994 1993 1994 ...
##  $ ride_length      : 'difftime' num [1:365069] 390 441 829 1783 ...
##   ..- attr(*, "units")= chr "mins"
##  $ week_day         : chr [1:365069] "martes" "martes" "martes" "martes" ...
##  $ num_week_day     : num [1:365069] 3 3 3 3 3 3 3 3 3 3 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Estructura

str(Divvy_Trips_2020_Q1)
## spc_tbl_ [426,887 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ ride_id           : chr [1:426887] "EACB19130B0CDA4A" "8FED874C809DC021" "789F3C21E472CA96" "C9A388DAC6ABF313" ...
##  $ rideable_type     : chr [1:426887] "docked_bike" "docked_bike" "docked_bike" "docked_bike" ...
##  $ started_at        : POSIXct[1:426887], format: "2020-01-21 20:06:59" "2020-01-30 14:22:39" ...
##  $ ended_at          : POSIXct[1:426887], format: "2020-01-21 20:14:30" "2020-01-30 14:26:22" ...
##  $ start_station_name: chr [1:426887] "Western Ave & Leland Ave" "Clark St & Montrose Ave" "Broadway & Belmont Ave" "Clark St & Randolph St" ...
##  $ start_station_id  : num [1:426887] 239 234 296 51 66 212 96 96 212 38 ...
##  $ end_station_name  : chr [1:426887] "Clark St & Leland Ave" "Southport Ave & Irving Park Rd" "Wilton Ave & Belmont Ave" "Fairbanks Ct & Grand Ave" ...
##  $ end_station_id    : num [1:426887] 326 318 117 24 212 96 212 212 96 100 ...
##  $ start_lat         : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ start_lng         : num [1:426887] -87.7 -87.7 -87.6 -87.6 -87.6 ...
##  $ end_lat           : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ end_lng           : num [1:426887] -87.7 -87.7 -87.7 -87.6 -87.6 ...
##  $ member_casual     : chr [1:426887] "member" "member" "member" "member" ...
##  $ ride_length       : 'difftime' num [1:426887] 451 223 171 529 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day          : chr [1:426887] "martes" "jueves" "jueves" "lunes" ...
##  $ num_week_day      : num [1:426887] 3 5 5 2 5 6 6 6 6 6 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   ride_id = col_character(),
##   ..   rideable_type = col_character(),
##   ..   started_at = col_datetime(format = ""),
##   ..   ended_at = col_datetime(format = ""),
##   ..   start_station_name = col_character(),
##   ..   start_station_id = col_double(),
##   ..   end_station_name = col_character(),
##   ..   end_station_id = col_double(),
##   ..   start_lat = col_double(),
##   ..   start_lng = col_double(),
##   ..   end_lat = col_double(),
##   ..   end_lng = col_double(),
##   ..   member_casual = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

Visualiza

View(Divvy_Trips_2019_Q1)

Visuliza

View(Divvy_Trips_2020_Q1)

CREACION DE VARIABLE EDAD EN Divvy_Trips_2019_Q1

Se genera una columna de “edad_cliente”, tomando de la tabla Divvy_Trips_2019_Q1, la columna “birthyear” restada el año 2025.

Divvy_Trips_2019_Q1$edad_cliente <- 2025 - Divvy_Trips_2019_Q1$birthyear

ELIMINACION COLUMNA rideable_type de tabla Divvy_Trips_2020

Se elimina de la tabla Divvy_Trips_2020 la columna rideable_type
se debe a que solo hace ruido, no tiene informacion adecuada para un analisis Llamamos la funcion colnames() para asegurarnos cual es el nombre de columna que se va eliminar

colnames(Divvy_Trips_2020_Q1)
##  [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"      "ride_length"        "week_day"          
## [16] "num_week_day"

Posterior realizamos a eliminacion

Divvy_Trips_2020_Q1 <- Divvy_Trips_2020_Q1 [,-2]

Nuevamente llamamos a la funcion colnames() y tambien lo visualizamos

colnames(Divvy_Trips_2020_Q1)
##  [1] "ride_id"            "started_at"         "ended_at"          
##  [4] "start_station_name" "start_station_id"   "end_station_name"  
##  [7] "end_station_id"     "start_lat"          "start_lng"         
## [10] "end_lat"            "end_lng"            "member_casual"     
## [13] "ride_length"        "week_day"           "num_week_day"

View(Divvy_Trips_2020_Q1)

colnames(Divvy_Trips_2020_Q1)
##  [1] "ride_id"            "started_at"         "ended_at"          
##  [4] "start_station_name" "start_station_id"   "end_station_name"  
##  [7] "end_station_id"     "start_lat"          "start_lng"         
## [10] "end_lat"            "end_lng"            "member_casual"     
## [13] "ride_length"        "week_day"           "num_week_day"

CAMBIO DE TIPO FORMATO NUMERICO A TEXTO

La Tabla Divvy_Trips_2019_Q1 se cambiara el tipo de formato de numero a texto de la columna trip_id es numerico y cuando queramos unir las tablas hay que tener el mismo el formato de la otra tabla Divvy_Trips_2020_Q1, que tiene si columna ride_id en formato texto.

Divvy_Trips_2019_Q1$trip_id <- as.character(Divvy_Trips_2019_Q1$trip_id)

Usamos la funcion str() para ver su estructura

str(Divvy_Trips_2019_Q1)
## spc_tbl_ [365,069 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ trip_id          : chr [1:365069] "21742443" "21742444" "21742445" "21742446" ...
##  $ start_time       : POSIXct[1:365069], format: "2019-01-01 00:04:37" "2019-01-01 00:08:13" ...
##  $ end_time         : POSIXct[1:365069], format: "2019-01-01 00:11:07" "2019-01-01 00:15:34" ...
##  $ bikeid           : num [1:365069] 2167 4386 1524 252 1170 ...
##  $ tripduration     : num [1:365069] 390 441 829 1783 364 ...
##  $ from_station_id  : num [1:365069] 199 44 15 123 173 98 98 211 150 268 ...
##  $ from_station_name: chr [1:365069] "Wabash Ave & Grand Ave" "State St & Randolph St" "Racine Ave & 18th St" "California Ave & Milwaukee Ave" ...
##  $ to_station_id    : num [1:365069] 84 624 644 176 35 49 49 142 148 141 ...
##  $ to_station_name  : chr [1:365069] "Milwaukee Ave & Grand Ave" "Dearborn St & Van Buren St (*)" "Western Ave & Fillmore St (*)" "Clark St & Elm St" ...
##  $ usertype         : chr [1:365069] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ gender           : chr [1:365069] "Male" "Female" "Female" "Male" ...
##  $ birthyear        : num [1:365069] 1989 1990 1994 1993 1994 ...
##  $ ride_length      : 'difftime' num [1:365069] 390 441 829 1783 ...
##   ..- attr(*, "units")= chr "mins"
##  $ week_day         : chr [1:365069] "martes" "martes" "martes" "martes" ...
##  $ num_week_day     : num [1:365069] 3 3 3 3 3 3 3 3 3 3 ...
##  $ edad_cliente     : num [1:365069] 36 35 31 32 31 42 41 35 30 29 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Tambien realizamos funcion summary() para ver algunas medidas descriptivas

summary(Divvy_Trips_2019_Q1)
##    trip_id            start_time                     end_time                  
##  Length:365069      Min.   :2019-01-01 00:04:37   Min.   :2019-01-01 00:11:07  
##  Class :character   1st Qu.:2019-01-23 05:26:54   1st Qu.:2019-01-23 05:49:40  
##  Mode  :character   Median :2019-02-25 07:52:56   Median :2019-02-25 08:03:50  
##                     Mean   :2019-02-19 21:43:15   Mean   :2019-02-19 22:00:11  
##                     3rd Qu.:2019-03-17 16:52:47   3rd Qu.:2019-03-17 17:16:16  
##                     Max.   :2019-03-31 23:53:48   Max.   :2019-06-17 16:04:35  
##                                                                                
##      bikeid      tripduration      from_station_id from_station_name 
##  Min.   :   1   Min.   :      61   Min.   :  2.0   Length:365069     
##  1st Qu.:1777   1st Qu.:     326   1st Qu.: 76.0   Class :character  
##  Median :3489   Median :     524   Median :170.0   Mode  :character  
##  Mean   :3429   Mean   :    1016   Mean   :198.1                     
##  3rd Qu.:5157   3rd Qu.:     866   3rd Qu.:287.0                     
##  Max.   :6471   Max.   :10628400   Max.   :665.0                     
##                                                                      
##  to_station_id   to_station_name      usertype            gender         
##  Min.   :  2.0   Length:365069      Length:365069      Length:365069     
##  1st Qu.: 76.0   Class :character   Class :character   Class :character  
##  Median :168.0   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :198.6                                                           
##  3rd Qu.:287.0                                                           
##  Max.   :665.0                                                           
##                                                                          
##    birthyear      ride_length              week_day          num_week_day  
##  Min.   :1900    Min.   :      61 mins   Length:365069      Min.   :1.000  
##  1st Qu.:1975    1st Qu.:     326 mins   Class :character   1st Qu.:3.000  
##  Median :1985    Median :     524 mins   Mode  :character   Median :4.000  
##  Mean   :1982    Mean   :    1016 mins                      Mean   :4.145  
##  3rd Qu.:1990    3rd Qu.:     866 mins                      3rd Qu.:6.000  
##  Max.   :2003    Max.   :10632022 mins                      Max.   :7.000  
##  NA's   :18023                                                             
##   edad_cliente   
##  Min.   : 22.00  
##  1st Qu.: 35.00  
##  Median : 40.00  
##  Mean   : 43.33  
##  3rd Qu.: 50.00  
##  Max.   :125.00  
##  NA's   :18023

CREANDO DE MEDIDAS DESCRIPTIVAS TABLA Divvy_Trips_2019_Q1

De la tabla Divvy_Trips_2019_Q1 la columna start_time creando un sumario de nombre Desc_Est_2019_Q1_StT

Desc_Est_2019_Q1_StT <- Divvy_Trips_2019_Q1 %>%
  summarise(
    mean_start_time = mean(Divvy_Trips_2019_Q1$start_time, na.rm = TRUE ),
    media_start_time = median(Divvy_Trips_2019_Q1$start_time, na.rm = TRUE ),
    desvst_start_time = round(sd(Divvy_Trips_2019_Q1$start_time, na.rm = TRUE ), digits = 2),
    min_start_time = min(Divvy_Trips_2019_Q1$start_time, na.rm = TRUE ),
    max_start_time = max(Divvy_Trips_2019_Q1$start_time, na.rm = TRUE ))

De la tabla Divvy_Trips_2019_Q1 la columna biked_id creando un sumario de nombre Desc_Est_2019_Q1_Bkid

Desc_Est_2019_Q1_Bkid <- Divvy_Trips_2019_Q1 %>%
    summarise(
    mean_bikeid = mean(Divvy_Trips_2019_Q1$bikeid, na.rm = TRUE ),
    media_bikeid = median(Divvy_Trips_2019_Q1$bikeid, na.rm = TRUE ),
    min_bikeid = min(Divvy_Trips_2019_Q1$bikeid, na.rm = TRUE ),
    max_bikeid = max(Divvy_Trips_2019_Q1$bikeid, na.rm = TRUE ),)

De la tabla Divvy_Trips_2019_Q1 la columna tripduration creando un sumario de nombre Desc_Est_2019_Q1_Tripd

Desc_Est_2019_Q1_Tripd <- Divvy_Trips_2019_Q1 %>%
    summarise(
    mean_Tripd = mean(Divvy_Trips_2019_Q1$tripduration, na.rm = TRUE ),
    media_Tripd = median(Divvy_Trips_2019_Q1$tripduration, na.rm = TRUE ),
    min_Tripd = min(Divvy_Trips_2019_Q1$tripduration, na.rm = TRUE ),
    max_Tripd = max(Divvy_Trips_2019_Q1$tripduration, na.rm = TRUE ),)

De la tabla Divvy_Trips_2019_Q1 la columna from_station_id creando un sumario de nombre Desc_Est_2019_Q1_FrStId

Desc_Est_2019_Q1_Tripd <- Divvy_Trips_2019_Q1 %>%
    summarise(
    mean_FrStId = mean(Divvy_Trips_2019_Q1$from_station_id, na.rm = TRUE ),
    media_FrStId = median(Divvy_Trips_2019_Q1$from_station_id, na.rm = TRUE ),
    min_FrStId = min(Divvy_Trips_2019_Q1$from_station_id, na.rm = TRUE ),
    max_FrStId = max(Divvy_Trips_2019_Q1$from_station_id, na.rm = TRUE ),)

CONTANDO REGISTROS DE TABLA Divvy_Trips_2019_Q1 VARIABLE “usertype”

De la tabla Divvy_Trips_2019_Q1 la columna “usertype” creando el conteo de porque es tipo texto pondremos de nombre Count_2019_UserT en ella se omite los datos N.A con la funcion na.omit()

Count_2019_UserT<- na.omit(Divvy_Trips_2019_Q1) %>%
      count(usertype)

Posterior verificamos el resultado de Count_2019_UserT, en el nos proposrciona que de la columna “usertype” tenemos las cantidades de “Customer” = 23163 y de “Subscriber” = 341906 estos son valores absolutos

str(Count_2019_UserT)
## tibble [2 × 2] (S3: tbl_df/tbl/data.frame)
##  $ usertype: chr [1:2] "Customer" "Subscriber"
##  $ n       : int [1:2] 5934 339423
##  - attr(*, "na.action")= 'omit' Named int [1:19712] 20 22 49 53 54 55 56 59 78 79 ...
##   ..- attr(*, "names")= chr [1:19712] "20" "22" "49" "53" ...

Visualiza

View(Count_2019_UserT)

Contar columna “gender” DE LA TABLA Divvy_Trips_2019_Q1

De la tabla Divvy_Trips_2019_Q1 la columna “gender” creando el conteo de porque es tipo texto pondremos de nombre Count_2019_Gender al mismo tiempo, se omite los valos N.A con la funcion na.omit()

 Count_2019_Gender<- na.omit(Divvy_Trips_2019_Q1) %>%
          count(gender)

Posterior verificamos el resultado de Count_2019_Gender, en el nos proposrciona que de la columna “gender” tenemos las cantidades de “Female” = 66918 y de “Male” = 278440 estos son valores absolutos

str(Count_2019_Gender)
## tibble [2 × 2] (S3: tbl_df/tbl/data.frame)
##  $ gender: chr [1:2] "Female" "Male"
##  $ n     : int [1:2] 66918 278439
##  - attr(*, "na.action")= 'omit' Named int [1:19712] 20 22 49 53 54 55 56 59 78 79 ...
##   ..- attr(*, "names")= chr [1:19712] "20" "22" "49" "53" ...

Visual

View(Count_2019_Gender)

Contar columna “edad_cliente” 2019

De la tabla Divvy_Trips_2019_Q1 la columna “edad_cliente” crea conteo de porque es tipo texto pondremos de nombre Count_2019_Edad

 Count_2019_Edad<- na.omit(Divvy_Trips_2019_Q1) %>%
          count(edad_cliente)

Posterior verificamos el resultado de Count_2019_Edad, nos proporciona que de la columna “edad_cliente” tenemos las cantidades de en este caso no mostramos por ser extenso el volumen de datos pero posteior en area de graficos se incluira un histograma

str(Count_2019_Edad)
## tibble [72 × 2] (S3: tbl_df/tbl/data.frame)
##  $ edad_cliente: num [1:72] 22 23 24 25 26 27 28 29 30 31 ...
##  $ n           : int [1:72] 2 79 118 820 1888 1668 1868 5296 8544 11432 ...
##  - attr(*, "na.action")= 'omit' Named int [1:19712] 20 22 49 53 54 55 56 59 78 79 ...
##   ..- attr(*, "names")= chr [1:19712] "20" "22" "49" "53" ...

Visual

View(Count_2019_Edad)

Dias de uso de bicicleta en la semana 2019

De la tabla Divvy_Trips_2019_Q1 la columna “week_day” crea conteo de porque es tipo texto pondremos de nombre Count_2019_WDay

Count_2019_WDay<- Divvy_Trips_2019_Q1 %>%
          count(week_day)

Ordenamos en forma descente con la funccion arrange(desc())

Count_2019_WDay<- Count_2019_WDay %>%
          arrange(desc(n))

Posterior verificamos el resultado de Count_2019_WDay, nos proposrciona que de la columna “week_day” tenemos las cantidades de “domingo” = 27999 ; “lunes” = 50399; “mates” = 61005; “miercoles” = 60414; “jueves”= 66903; “viernes” = 63047; “sabado”= 35302 Nos indica que entre semana hay mas uso siendo el dia jueves el mas alto

str(Count_2019_WDay)
## spc_tbl_ [7 × 2] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ week_day: chr [1:7] "jueves" "viernes" "martes" "miércoles" ...
##  $ n       : int [1:7] 66903 63047 61005 60414 50399 35302 27999
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Visual

View(Count_2019_WDay)

FITRADO DE TABLA Divvy_Trips_2019_Q1

Se realizara el uso de filtros de varias columnas relevantes, para obtener informacion epecifica recordamos que es las columnas son tipo character es decir texto es importante recordar.

Iniciaremos el filtrado de usertype “Customer” De la tabla Divvy_Trips_2019_Q1 la columna usertype generamos un filtro de tipo de cliente “Customer” para ello lo guardaremos con nombre filt_2019_UserT_C usamos la funcion filter(), usamos == para que sea exacto

filt_2019_UserT_C <- Divvy_Trips_2019_Q1 %>%
      filter( usertype == "Customer")

Ahora contamos el numero de “Customer de filt_2019_UserT_C con la funcion count()

Count_filt_2019_UserT_C <- filt_2019_UserT_C %>%
      count(usertype)

De la tabla Divvy_Trips_2019_Q1 la columna usertype generamos un filtro de tipo de cliente “Subscriber” para ello lo guardaremos con nombre filt_2019_UserT_S usamos la funcion filter(), usamos == para que sea exacto

filt_2019_UserT_S <- Divvy_Trips_2019_Q1 %>%
      filter( usertype == "Subscriber")

Contamos el numero de “Customer de filt_2019_UserT_S con la funcion count()

Count_filt_2019_UserT_S <- filt_2019_UserT_S %>%
      count(usertype)

Se filtrara la tabla Divvy_Trips_2019_Q1 las columnas usertype solo “Customer” y gender se usa para indicarle una lista de valores usamos %in% y lista de vectores c(“Male”,“Female”), podemos visualizar la tabla, nos refleja que de usuarios “Customer” hay 5935 entre “Male” y “Female”.

filt_user_gend <- Divvy_Trips_2019_Q1 %>%
      filter(usertype == "Customer" & gender %in% c("Male","Female"))

Realizando una seleccionamos solo las columnas usertype y “gender”, de eses columnas, se filtra el tipo de cliente “Customer” y de la columana “gender” ambos generos “Females y Male” “Customer”, ademasy gender. De esta manera realizamos en una sola sentencia la seleccion y filtrado generando una subtabla llamada sel_user_gend_C

sel_user_gend_C <- Divvy_Trips_2019_Q1 %>%
      select ("usertype", "gender") %>%
      filter (usertype == "Customer" & gender %in% c("Male","Female")) 

Con estas eleccion podemos filtrar por genero de los clientes “Customer”. ahora seleccionamos el genero “Female”, esto lo ubicaremos en una tabla llamada Filt_user_gend_C_F, usando la subtabla sel_user_gend_C, nos indica los Clientes “Customer” “Female” son 1875

Filt_user_gend_C_F <- sel_user_gend_C %>%
      select ("usertype", "gender") %>%
      filter (usertype == "Customer" & gender=="Female") 

Conteo

count(Filt_user_gend_C_F)

Se hara lo mismo pero para “Male” con las mismas columnas pondremos de nombre a la subtabla Filt_user_gend_C_M

Filt_user_gend_C_M <- sel_user_gend_C %>%
      select ("usertype", "gender") %>%
      filter (usertype == "Customer" & gender=="Male")

Podemos visualizar con la funcion count(), no entrega la cantidad de “Male” que es de 4060

count(Filt_user_gend_C_M)

De la misma manera que el anterior sentencia, vamos a crear y seleccionar
columnas usertype y seleccionamos el cliente “Subscriber” y gender, ambos generos, creamos una subtabla llamada sel_user_gend_S

 sel_user_gend_S <- Divvy_Trips_2019_Q1 %>%
      select ("usertype", "gender") %>%
      filter (usertype == "Subscriber" & gender %in% c("Male","Female"))

Filtramos el tipo de clientre “Subscriber”, por el genero “Female”, generamos una subtabla llamada Filt_user_gend_S_F usando la tabla sel_user_gend_S

Filt_user_gend_S_F <- sel_user_gend_S %>%
      select ("usertype", "gender") %>%
      filter (usertype == "Subscriber" & gender=="Female")

Podemos visualizar con la funcion count(), entrega la cantidad de “Female” que es de 65043

count(Filt_user_gend_S_F)

De igual manera haresmo un filtro para clients “Male” crenado la subtabla
Filt_user_gend_S_M utilizando la subtabla sel_user_gend_S

 Filt_user_gend_S_M <- sel_user_gend_S %>%
       select ("usertype", "gender") %>%
       filter (usertype == "Subscriber" & gender=="Male")

Podemos visualizar con la funcion count(), entrega la cantidad de “Male” que es de 274380

count(Filt_user_gend_S_M)

Seleccion de columnas “usertype” y “tripduration” 2019

A continuacion realizamos una seleccion de dos columnas la misma que la denominaremos sel_user_durt

sel_user_durt <- Divvy_Trips_2019_Q1 [c("usertype" , "tripduration")]

Usamos la tabla sel_user_durt para filtrar proporcionar otro filtro entre columnas usertype solo “Customer” y tripduration con una condicion que sea mayor o igual a 1 pondremos de nombre al filtro filt_user_durt_C

 filt_user_durt_C <- sel_user_durt %>%
      filter(usertype == "Customer" & tripduration > 1)

Generar una tabla summario que se guardara en TabS_User_Durt_C

TabS_User_Durt_C <- table(summary(filt_user_durt_C))

Visual

View(TabS_User_Durt_C)

Uso de group_by() y summarise() para guardar el promedio mean() de filt_user_durt_C lo guardamos en Grby_filt_user_durt_C

Grby_filt_user_durt_C <- filt_user_durt_C %>%
      group_by(usertype) %>%
      summarise(mean = mean (tripduration))

Imprimir

print (Grby_filt_user_durt_C)
## # A tibble: 1 × 2
##   usertype  mean
##   <chr>    <dbl>
## 1 Customer 3716.

La tabla sel_user_durt para filtrar prporcionar otro filtro entre columnas usertype solo “Subscriber” y tripduration con una condicion que sea mayor o igual a 1 pondremos de nombre al filtro filt_user_durt_S

 filt_user_durt_S <- sel_user_durt %>%
      filter(usertype == "Subscriber" & tripduration > 1) 

Generamos tabla summario con la funcion summary() de TabS_User_Durt_S

TabS_User_Durt_S <- table(summary(filt_user_durt_S))

Visual

View(TabS_User_Durt_S)

Lo mismo realizamos usando group_by() y summarise() para guardar el promedio mean() filt_user_durt_S se guarda en Grby_filt_user_durt_S

Grby_filt_user_durt_S <- filt_user_durt_S %>%
      group_by(usertype) %>%
      summarise(mean = mean (tripduration))

Imprimir

print(Grby_filt_user_durt_S)
## # A tibble: 1 × 2
##   usertype    mean
##   <chr>      <dbl>
## 1 Subscriber  833.

Vemos que el promedio general en tripduration 473.2, mientras que filtrado por usertype cliente “Subscriber” tiene un tripduration 469, en cambio los usuarios “Customer” 617, son datos relevantes para el analisis.

SELECCION, FILTRADO Y AGRUPADO DE ride_length 2019

Ahora seleccionaremos con la funcion select usertype y ride_length, para ello crearemos tabla llamada Sel_User_RidL

Sel_User_RidL <- Divvy_Trips_2019_Q1 [c("usertype" , "ride_length")]
    summary(Sel_User_RidL)
##    usertype          ride_length           
##  Length:365069      Min.   :      61 mins  
##  Class :character   1st Qu.:     326 mins  
##  Mode  :character   Median :     524 mins  
##                     Mean   :    1016 mins  
##                     3rd Qu.:     866 mins  
##                     Max.   :10632022 mins

Se realiza el filtrado de la tabla Sel_User_RidL de columnas usertype los “Customer” junto con la columna “ride_length” indicando que es mayor a cero Nota. los datos que se visualizan son en segundos no en minutos

Filt_Sel_User_RidL_C <- Sel_User_RidL %>%
          filter(usertype == "Customer" & ride_length > 0)

Realizamos un resumen sumario con la funcion summary() de Filt_Sel_User_RidL_C con el motivo de mirar algunas medidas Nota. los datos que se visualizan son en segundos no en minutos

summary(Filt_Sel_User_RidL_C)
##    usertype          ride_length           
##  Length:23163       Min.   :      61 mins  
##  Class :character   1st Qu.:     809 mins  
##  Mode  :character   Median :    1401 mins  
##                     Mean   :    3717 mins  
##                     3rd Qu.:    2311 mins  
##                     Max.   :10632022 mins

Se genera un group_by del promedio de Filt_Sel_User_RidL_C con la intencion de comparar con otros resusltados posterioes
Nota. los datos que se visualizan son en segundos no en minutos

 Grby_Filt_Sel_User_RidL_C <- Filt_Sel_User_RidL_C %>%
      group_by(usertype) %>%
      summarise(mean = mean (ride_length))

Se realiza el filtrado de la tabla Sel_User_RidL de columnas usertype los “Subscriber” junto con la columna “ride_length” indicando que es mayor a cero Pondremos de nombre al filtro Filt_Sel_User_RidL_s Nota. los datos que se visualizan son en segundos no en minutos

Filt_Sel_User_RidL_S <- Sel_User_RidL %>%
      filter(usertype == "Subscriber" & ride_length > 0)

Realizamos un resumen sumario con la funcion summary() de Filt_Sel_User_RidL_S con el motivo de mirar algunas medidas Nota. los datos que se visualizan son en segundos no en minutos

summary(Filt_Sel_User_RidL_S)
##    usertype          ride_length            
##  Length:341906      Min.   :     61.0 mins  
##  Class :character   1st Qu.:    317.0 mins  
##  Mode  :character   Median :    501.0 mins  
##                     Mean   :    833.6 mins  
##                     3rd Qu.:    802.0 mins  
##                     Max.   :6096428.0 mins

Genreraremos un group_by del promedio de Filt_Sel_User_RidL_S con la intencion de comparar con otrso resusltados posterioes
Nota. los datos que se visualizan son en segundos no en minutos

 Grby_Filt_Sel_User_RidL_S <- Filt_Sel_User_RidL_S %>%
      group_by(usertype) %>%
      summarise(mean = mean (ride_length))

Tablas relevantes e Informativas

Antes de realizar cualquier grafico generamos la tabla denominada Count_Sel_User_RidL_U Cuenta la tabla y se conforma por porcentaje unicamente clientes la columna “usertype” # de la tabla Sel_User_RidL.
En este caso se utiliza la tabla con formula “percent = n/sum(n)*100”, porque “no” es un argumento numerico.

Count_Sel_User_RidL_U <- Sel_User_RidL %>%
  count(usertype) %>%
  mutate (percent = n/sum(n)*100)  # argumento no numerico

Se genera otra tabla denominada Count_Sel_User_RidL_R ,en porcentaje unicamente tiempo de uso de las bicicletas de la columna “ride_length” usando tabla Sel_User_RidL, en esta tabla el porcentaje atravez pero nos da en toda la tabla su promedio general. La funcion mutate() nos permite calcular el promedio mean(), esta tabla es solo informativa.

Count_Sel_User_RidL_R <- Sel_User_RidL %>%
  count(ride_length) %>%
  mutate(mean_percent=mean(ride_length)) # argumento numerico

Asi mismo gerera una tabla no relevante pero informativa de las columnas usertype y ride_lenght juntas denominada Count_Sel_User_RidL_UR. Genera el calculo a traves de la funcion mutate(), obteniendo el promedio mean() de la columna ride_length, de la tabla Sel_User_RidL

Count_Sel_User_RidL_UR <- Sel_User_RidL %>%
  count(usertype, ride_length) %>%
  mutate( mean_percent=mean(ride_length)) # argumento numerico

Generamos tres sumarios de Count_Sel_User_RidL_U, Count_Sel_User_RidL_R y Count_Sel_User_RidL_UR y vemos su estructura str()

summary(Count_Sel_User_RidL_U)
##    usertype               n             percent      
##  Length:2           Min.   : 23163   Min.   : 6.345  
##  Class :character   1st Qu.:102849   1st Qu.:28.172  
##  Mode  :character   Median :182535   Median :50.000  
##                     Mean   :182535   Mean   :50.000  
##                     3rd Qu.:262220   3rd Qu.:71.828  
##                     Max.   :341906   Max.   :93.655

Sumario

summary(Count_Sel_User_RidL_R)
##   ride_length                  n           mean_percent       
##  Min.   :      61 mins   Min.   :  1.00   Min.   :19281 mins  
##  1st Qu.:    1728 mins   1st Qu.:  1.00   1st Qu.:19281 mins  
##  Median :    3430 mins   Median :  3.00   Median :19281 mins  
##  Mean   :   19281 mins   Mean   : 54.76   Mean   :19281 mins  
##  3rd Qu.:    6262 mins   3rd Qu.: 33.00   3rd Qu.:19281 mins  
##  Max.   :10632022 mins   Max.   :586.00   Max.   :19281 mins

Sumario

summary(Count_Sel_User_RidL_UR)  
##    usertype          ride_length                  n         
##  Length:10066       Min.   :      61 mins   Min.   :  1.00  
##  Class :character   1st Qu.:    1343 mins   1st Qu.:  1.00  
##  Mode  :character   Median :    2612 mins   Median :  3.00  
##                     Mean   :   13441 mins   Mean   : 36.27  
##                     3rd Qu.:    4691 mins   3rd Qu.: 11.00  
##                     Max.   :10632022 mins   Max.   :573.00  
##   mean_percent       
##  Min.   :13441 mins  
##  1st Qu.:13441 mins  
##  Median :13441 mins  
##  Mean   :13441 mins  
##  3rd Qu.:13441 mins  
##  Max.   :13441 mins

Sumario

summary(Sel_User_RidL)
##    usertype          ride_length           
##  Length:365069      Min.   :      61 mins  
##  Class :character   1st Qu.:     326 mins  
##  Mode  :character   Median :     524 mins  
##                     Mean   :    1016 mins  
##                     3rd Qu.:     866 mins  
##                     Max.   :10632022 mins

Estructura

str(Count_Sel_User_RidL_U)
## tibble [2 × 3] (S3: tbl_df/tbl/data.frame)
##  $ usertype: chr [1:2] "Customer" "Subscriber"
##  $ n       : int [1:2] 23163 341906
##  $ percent : num [1:2] 6.34 93.66

Estructura

str(Count_Sel_User_RidL_R)
## tibble [6,667 × 3] (S3: tbl_df/tbl/data.frame)
##  $ ride_length : 'difftime' num [1:6667] 61 62 63 64 ...
##   ..- attr(*, "units")= chr "mins"
##  $ n           : int [1:6667] 30 24 27 25 26 28 25 33 22 16 ...
##  $ mean_percent: 'difftime' num [1:6667] 19280.5087745613 19280.5087745613 19280.5087745613 19280.5087745613 ...
##   ..- attr(*, "units")= chr "mins"

Estructura

str(Count_Sel_User_RidL_UR)
## tibble [10,066 × 4] (S3: tbl_df/tbl/data.frame)
##  $ usertype    : chr [1:10066] "Customer" "Customer" "Customer" "Customer" ...
##  $ ride_length : 'difftime' num [1:10066] 61 63 64 67 ...
##   ..- attr(*, "units")= chr "mins"
##  $ n           : int [1:10066] 4 1 1 1 1 1 1 1 3 2 ...
##  $ mean_percent: 'difftime' num [1:10066] 13441.1175243394 13441.1175243394 13441.1175243394 13441.1175243394 ...
##   ..- attr(*, "units")= chr "mins"

GRAFICOS

Se creara graficos en este caso de informacion relevante para el analisis no basamos en ciertas normativa que los expertos aplican para graficos, los mismos que tendran todos los graficos , como indica los expertos podremos una nomenclatura para los graficos en este caso la letra P y numero en el primer grafico le designaremos P1 asi consecutivamente cada grafico.

Esta es una formula permite graficar el numero por tipo de cliente y su porcentaje de la tabla Count_Sel_User_RidL_U la columna usertype, se usa geom_col, porque con ella se puede contar cada cliente indvidual y tambien su porcentaje individual por cada cliente, la funcion “paste0”, se refiere a concatenar multiples cadenas de texto en una solo, sin uso de separadores (sin espacios) de texto para concatenar, mientra que la funcion”vjust()” se usa para que las etiquetas quede encima de las barras.

Adicionalmente usaremos la funsion colors(), nos muestra listado de colores, todo grafico se usara, en su mayoria dos tonalidades skyblue1 y lightblue

Grafico Tipo de Cliente por Cantidad y su Porcentaje 2019

P1 <- ggplot(data=Count_Sel_User_RidL_U, aes(x=usertype, y=n, fill= usertype))+
geom_col()+
geom_text(aes(label=paste0(n, " (", round(percent,1),"%)")), vjust = -0.5)+
scale_fill_manual(values = c("skyblue1","lightblue"))+ 
labs(title= "Tipo de Cliente por\nCantidad y su Porcentaje 2019",
     x="Clientes", y="Cantidad",
     caption = "Data: Empresa Motivate International Inc\nP1")+
theme(plot.title = element_text(hjust = 0.5),legend.position = "none")  

label=paste0. Se usa para concatenar, usando una cadena de caracteres vacios como separador.
Utilizamos vjust=-0.5, para poner las etiqueta encima de las barras scale_fill_manual.Cambia los colores de relleno manualmente ya expuestos
En la sentencia anterior centramos el titulo con la funcion hjust()

Visual

P1

El grafico P1 nos da la visualizacion del Tipo de Cliente y su Porcentaje, en el nos muestra que “Subscriber” tiene 341906 con un 93.7%, mientras clientes “Customer” tiene 23163 con el 6.34%.

Grafico tipo de Cliente por Tiempo de Recorrido Promedio

Generamos una tabla del promedio con la tabla “Sel_User_RidL” del tiempo recorrido por tipo de cliente. Se denominara Main_Count_Sel_User_RidL_UR, en ella agruparemos con funcion group_by() por tipo de usuario y resumido por la funcion summarise () en la que la columna ride_length la convierte en numerico con la funcion as.numeric() y podremos calcular con la funcion mutate() y el promedio con la funcion mean() Usamos esta tabla simplemente porque, es similar la la tabla “sel_user_durt”, solo con proposito practico.

Promedio

Main_Count_Sel_User_RidL_UR <- Sel_User_RidL %>%
  group_by(usertype) %>%
  summarise(
        Mean_Rd_Length = as.numeric(mean(ride_length, na.rm = TRUE)))%>%
  mutate( percent = Mean_Rd_Length / sum(Mean_Rd_Length)*100 )

La Tabla muestra el resultado es que la trayectoria que recorren clientes “Customer” es de 222990.94, siendo un 81.7% mientras que los los clientes “Subscribes” es de 50014.33, siendo el 18.3% de tiempo recorrido por tipo de cliente, generamos un grafico para visualizar los datos, el que denominaremos P2

Creamos grafico denominado P2 de la tabla del Promedio del Tiempo y

Clasificado por el Tipo Cliente.

P2 <- ggplot(data=Main_Count_Sel_User_RidL_UR, aes(x = usertype, 
                                 y = Mean_Rd_Length, fill = usertype)) +
geom_col() +
geom_text(aes(label=paste0(round(Mean_Rd_Length,1), " (",round(percent,1),"%)"))
                    , vjust = -0.5)+
  scale_fill_manual(values = c("skyblue1","lightblue"))+ 
 labs(title =  "Tipo de Cliente por Tiempo\nRecorrido y su Promedio en % 2019",
     x= "Clientes", y = "Promedio del Tiempo Recorrido", 
     caption = "Data: Empresa Motivate International Inc\nP2")+
theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

nota.- scale_fill_manual para asignación manual de colores

Visualizacion

P2

GRAFICOS PARALELOS P1 Y P2

Mostraremos como una especie de resumen pero con graficos paralelos P1 y P2 esta manera se puede comparar las graficas

(P1 + P2)+
  plot_annotation(
    title="Distribucion por TIPO DE CLIENTE",
    theme=theme(plot.title = element_text(hjust = 0.5)))

Si bien podemos visualizar la cantidades de “Customer” es inferior a “Subscriber”, no da indicios que las campañas de marketing para subscribirse, han tenido un gran exito como podemos ver en la visualizacion y un parte de proponer una nueva campaña de marketing, se sotiene por el tiempo promedio recorrido de “Customer” superior al de “Subscriber”, demustra la gran acogida, que tiene las bicicletas compartidas.

Uso de Bicicletas por Dia de la Semana 2019

Seleccionamos tabla Count_2019_WDay que contiene los datos, pero al ver su estructura de la columna week_day es character y se cambiara a factor, permite que se pueda manipular los datos.

Count_2019_WDay$week_day<-factor( Count_2019_WDay$week_day,
  levels=Count_2019_WDay$week_day)

Ahora se realizara la creacion de una nueva columna en tabla Count_2019_WDay, para obtener el porcentaje en una columna nueva llamada “percent”.

Count_2019_WDay <- Count_2019_WDay %>%
  mutate(percent=round(n/sum(n)*100,2))

Grafico denominado P3 para Uso de bicicleta por dia de la semana 2019

P3 <- ggplot(data = Count_2019_WDay , aes(x=week_day, y=n, fill = n ))+
  geom_bar (stat = "identity")+
 geom_text(aes(label=paste0(round(n,1), "\n (",round(percent,1),"%)"))
        # "\n Es el salto de linea 
             , vjust = -0.3 , size = 4 )+
  expand_limits(y = max(Count_2019_WDay$n) * 1.15) +
     labs(title =  "Uso de Bicicletas por Dia de la Semana 2019",
       x= "Dia de la Semana", y = "Tiempo Recorrido por Dia ", 
       caption = "Data: Empresa Motivate International Inc\nP3")+
        theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

nota.- expand_limits:funcion que amplia un eje (x o y) sin cambiar datos (etiquetas)

Visualizacion

P3

Tanto en la tabla Count_2019_WDay, como en el grafico nos muestra, que el dia de mayor uso es el dia jueves con 66903 corresponde 18.3%, notamos los dias de mayor uso, son dias entre semana, lo que muestra que los clientes usan para labores cotidianas y en menor escala los fines de semana.

Grafico Usuarios por Estaciones 2019

Seleccion de variables usertype y from_station_id 2019, para crear grafico

Sel_User_Station <- Divvy_Trips_2019_Q1 [c("usertype" , "from_station_id")]

Grafico P4

P4<- ggplot(data = Sel_User_Station,aes(x=from_station_id, fill = usertype ) )+
  geom_histogram(aes(y=after_stat(density)), binwidth = 5, position="dodge", 
                  color = "blue", alpha=0.6)+
  geom_density(aes( color = usertype, linewidth = 1)) +
  facet_wrap(~ usertype , nrow = 1)+
  labs( title = "Estaciones por Usuarios 2019",x = "Estaciones",y = "Densidad",
        caption = "Data: Empresa Motivate International Inc\nP4") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Visual

P4

Grafico Rango por Edades 2019

EStructura

str (Count_2019_Edad)
## tibble [72 × 2] (S3: tbl_df/tbl/data.frame)
##  $ edad_cliente: num [1:72] 22 23 24 25 26 27 28 29 30 31 ...
##  $ n           : int [1:72] 2 79 118 820 1888 1668 1868 5296 8544 11432 ...
##  - attr(*, "na.action")= 'omit' Named int [1:19712] 20 22 49 53 54 55 56 59 78 79 ...
##   ..- attr(*, "names")= chr [1:19712] "20" "22" "49" "53" ...

Calculo del promedio de Edad 2019

Count_2019_Edad <- Count_2019_Edad %>%
  mutate(percent=round(n/sum(n)*100,2))

Rangos por Edad 2019

Rang_Edad_2019 <- Count_2019_Edad %>%
  mutate(
    Edad_Rang=case_when(edad_cliente>20 & edad_cliente<=40 ~1,
                        edad_cliente>=41 &edad_cliente<=60 ~2,
                        edad_cliente>=61~3))

Con el rango establecido Rang_Edad_2019, juntaremos con a la tabla Count_2019_Edad,con la funcion cbind(), que agrega una columna a una tabla de datos, que tenga coincidencia con el mismo numero de filas de la tabla existente.Pero pondremos un nombre diferente que loa guardaremos como Rang_Edad_2019.

Ahora sacaremos el porcentaje de cada rango de la tabla Rang_Edad_2019

Rang_Edad_2019<- Rang_Edad_2019 %>%
  group_by (Edad_Rang) %>%
 summarise(n= sum(n)) %>%
  mutate(percent= round(n/ sum(n)*100,2))

Estructura

str(Rang_Edad_2019)
## tibble [3 × 3] (S3: tbl_df/tbl/data.frame)
##  $ Edad_Rang: num [1:3] 1 2 3
##  $ n        : int [1:3] 177336 131685 36336
##  $ percent  : num [1:3] 51.4 38.1 10.5

Visual

View(Rang_Edad_2019)

Grafico de Rangos por edad 2019

P5 <- ggplot(data=Rang_Edad_2019, aes(x=Edad_Rang,y=n, fill = Edad_Rang))+
  geom_col(stat = "identity", position = "dodge")+
geom_text(aes(label=paste0(n, " (", round(percent,1),"%)"))
          , vjust = -0.5)+
scale_x_continuous(breaks = c(1,2,3),
                   labels = c("20 a 40","41 a 60","61 a +" ))+
    labs(title =  "Rango por Edades 2019",
       x= "Rangos por Edades ", y = "Cantidad de Edades por Rangos 2019", 
       caption = "Data: Empresa Motivate International Inc\nP5")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Visual

P5

nota.-scale_x_continuous: Se usa cuando el rango es numerico, cambia las etiquetas nota.- del eje x por textos, crea vectores llamados breaks() y labels().

Grafico Paralelos Distribucion por Edades 2019

(P4 + P5)+
plot_annotation(
  title="Distribucion por Edades",
            theme=theme(plot.title = element_text(hjust = 0.5,size=14)))

Grafico P6 por tipo de usuario, genero edad 2019

Seleccion de variables en vector

Sel_User_Gndr_Edad<- Divvy_Trips_2019_Q1 [c("usertype","gender","edad_cliente")]

Omision de N.A en Sel_User_Gndr_Edad

Sel_User_Gndr_Edad <- na.omit(Sel_User_Gndr_Edad)

Promedio de edad de Sel_User_Gndr_Edad

Mean_Edad<-mean(Sel_User_Gndr_Edad$edad_cliente)

Grafico P6 por tipo de usuario, genero edad 2019

P6 <- ggplot(data = Sel_User_Gndr_Edad,aes(x=edad_cliente) )+
  geom_histogram(aes(y= after_stat(density)),
  binwidth = 5,
  fill = "skyblue",
  color = "black",
  alpha = 0.6) +
  geom_density(color = "blue", linewidth = 1) +
  geom_vline(aes(xintercept = mean(edad_cliente)),
  color="blue", linetype="dashed", size=1)+
  annotate("text",x=Mean_Edad,y = Inf,
    label = paste("        ", round(Mean_Edad, 1)),
    vjust = 1.5,
    color = "blue",
    size = 4 ) +
  labs( title = "Densidad de la Edad de Clientes\ny Promedio General de Edad2019",
    x = "Edad", y = "Densidad de Edad",
    caption = "Data: Empresa Motivate International Inc\nP6")+
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Visual

P6

Grafico Estaciones por Tipo Cliente y Genero 2019

Seleccion de variables dentro de vectores

Sel_User_Gen_Station <- Divvy_Trips_2019_Q1 [
  c("usertype" ,"gender", "from_station_id")]

Omision de N.A en Sel_User_Gen_Station

Sel_User_Gen_Station<- na.omit(Sel_User_Gen_Station)

Grafico P7 Estaciones por Tipo Cliente y Genero

P7 <- ggplot(data=  Sel_User_Gen_Station,
  aes(x = from_station_id, fill = usertype)) +
  geom_histogram(    aes(y = after_stat(density)),
    binwidth = 5,
    position = "dodge",
    alpha = 0.6  ) +
  geom_density( aes(color = gender), linewidth = 1  ) +
  facet_wrap(~ usertype, nrow = 1) +
  labs(    title = "Estaciones por\nTipo Cliente y Genero 2019",
    x = "Estaciones",
    y = "Densidad",
    caption = "Data: Empresa Motivate International Inc\nP7" ) +
  theme_minimal() +
  theme(    plot.title = element_text(hjust = 0.5)  )

Visual

P7

Grafico parelelo P4 y P7

(P4 + P7)+
  plot_annotation(
    title="Distribucion por Estaciones por\nTipo de Cliente y Genero",
    theme=theme(plot.title = element_text(hjust = 0.5,size=14)))

Grafico histograma y Linea de Densidad y de edad, genero 2019 P8

P8<- ggplot(data = Sel_User_Gndr_Edad,aes(x=edad_cliente, fill = gender) )+
  geom_histogram(aes(y=after_stat(density)), binwidth = 5, position="dodge", 
                 fill="skyblue", color = "blue", alpha=0.1)+
  geom_density( color = "lightblue",    linewidth = 1) +
  facet_wrap(~ gender, nrow = 1)+
  geom_vline(aes(xintercept = mean(edad_cliente)),
             color="blue", linetype="dashed", size=1)+
  annotate("text",x=Mean_Edad,y = Inf,
           label = paste("        ", round(Mean_Edad, 1)),
           vjust = 1.5,
           color = "blue",
           size = 4 ) +
  labs( title = "Densidad de Edades por Genero 2019",x = "Edad",y = "Densidad",
        caption = "Data: Empresa Motivate International Inc\nP8") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Visual

P8

Visual

View(Sel_User_Gndr_Edad)

Graficos paralelos P6 y P8

(P6 + P8)+
  plot_annotation(
    title="Distribucion por Edades",
    theme=theme(plot.title = element_text(hjust = 0.5,size=14)))

Calcula la media de edad para uso de grafico P9 2019

Media_Edad <- Sel_User_Gndr_Edad %>%
  group_by(usertype, gender) %>%
  summarise(media_edad = mean(edad_cliente, na.rm = TRUE), .groups = "drop")

Grafico Distribución de la Edad por Tipo de Cliente y Género 2019

P9 <- ggplot(data = Sel_User_Gndr_Edad,  aes(x = usertype,
                                        y = edad_cliente, fill = gender)) + 
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.4) +
  geom_text(data = Media_Edad, aes(x = usertype, y = media_edad, 
                     label = paste0("Edad\nMedia: ", round(media_edad, 1))),
    vjust=-0.5, color="blue", size=4)+               
    facet_wrap(~ gender) +
  scale_fill_manual(values = c("Male" = "skyblue", "Female" = "pink" ))+
  labs(    title = "Distribucion de la Edad por\nTipo de Cliente y Genero 2019",
    x = "Tipo de Cliente",    y = "Edad", 
    caption = "Data: Empresa Motivate International Inc\nP9" ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5), legend.position = "none" )
P9

Doble graficos P8 + P9

(P8 + P9)+
  plot_annotation(
    title="Densidades y Distribucion por\nTipo de Cliente, Edades, Genero 2019",
    theme=theme(plot.title = element_text(hjust = 0.5,size=14)))

2020

En este apartado existira menor consultas por motivos de la misma tabla Divvy_Trips_2020_Q1 que no tiene el mismo contenido que la anteior.

Ahora seleccionaremos las variables member_casual y ride_length, para ello crearemos tabla llamada Sel_User_RidL_2020

Sel_User_RidL_2020 <- Divvy_Trips_2020_Q1 [c("member_casual" , "ride_length")]

Calculo de porcentaje de variable member_casual de tabla Sel_User_RidL_2020

Count_Sel_User_RidL_2020 <- Sel_User_RidL_2020 %>%
  count(member_casual ) %>%
  mutate (percent = n/sum(n)*100)  

nota.-Argumento no numerico

GRAFICO Tipo de Cliente por Cantidad y su Porcentaje 2020

P10 <- ggplot(data=Count_Sel_User_RidL_2020, aes(x=member_casual, y=n, 
                                                 fill= member_casual))+
  geom_col()+
  geom_text(aes(label=paste0(n, " (", round(percent,1),"%)"))
            , vjust = -0.5)+
    scale_fill_manual(values = c("skyblue1","lightblue"))+ 
    labs(title= "Tipo de Cliente por\nCantidad y su Porcentaje 2020  ",
       x="Clientes", y="Cantidad",
       caption = "Data: Empresa Motivate International Inc\nP10")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Nota.-label=paste0. Se usa para concatenar, usando una cadena de caracteres vacios como separador. Nota.-Utilizamos vjust=-0.5, para poner las etiqueta encima de las barras Nota.-scale_fill_manual.Cambia los colores de relleno manualmente ya expuestos Nota.-En la sentencia anterior centramos el titulo con la funcion hjust()

Visualizamos

P10

El grafico P10 nos da la visualizacion del Tipo de Cliente y su Porcentaje, en el nos muestra que “Members” tiene 341906 con un 93.7%, mientras clientes “Casual” tiene 23163 con el 6.34%.

Uso de bygroup para agrupar por tipo de cliente y obtener la media 2020

Main_Count_Sel_User_RidL_2020 <- Sel_User_RidL_2020 %>%
  group_by(member_casual) %>%
  summarise(
    Mean_Rd_Length = as.numeric(mean(ride_length, na.rm = TRUE)))%>%
  mutate( percent = Mean_Rd_Length / sum(Mean_Rd_Length)*100 )

La Tabla muestra el resultado es que la trayectoria que recorren clientes “Casual” es de 5746.9586, siendo un 88.31% mientras que los los clientes “Members” es de 760.6268, siendo el 11.68% de tiempo recorrido por tipo de cliente, generamos un grafico para visualizar los datos, el que denominaremos P11

Creamos grafico denominado P11 de la tabla del Promedio del Tiempo y

Clasificado por el Tipo Cliente. 2020

P11 <- ggplot(data=Main_Count_Sel_User_RidL_2020, aes(x = member_casual, 
                                                   y = Mean_Rd_Length, fill = member_casual)) +
  geom_col() +
  geom_text(aes(label=paste0(round(Mean_Rd_Length,1), " (",round(percent,1),"%)"))
            , vjust = -0.5)+
  scale_fill_manual(values = c("skyblue1","lightblue"))+ 
  # scale_fill_manual para asignación manual de colores
  labs(title =  "Tipo de Cliente por Tiempo\nRecorrido y su Promedio en % 2020",
       x= "Clientes", y = "Promedio del Tiempo Recorrido", 
       caption = "Data: Empresa Motivate International Inc\nP11")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

GRAFICOS PARALELOS P10 Y P11 2020

Mostraremos como una especie de resumen pero con graficos paralelos P10 y P11 esta manera se puede comparar las graficas

(P10 + P11)+
  plot_annotation(
    title="Distribucion por Tipo de Cliente 2020",
    theme=theme(plot.title = element_text(hjust = 0.5)))

Dias de uso de bicicleta en la semana 2020

De la tabla Divvy_Trips_2020_Q1 la columna “week_day” crea conteo de porque es tipo texto pondremos de nombre Count_2019_WDay

Count_2020_WDay<- Divvy_Trips_2020_Q1 %>%
  count(week_day)

Ordenamos en forma descente de la variable “n” con la funcion arrange(desc())

Count_2020_WDay<- Count_2020_WDay %>%
  arrange(desc(n))

Posterior verificamos el resultado de Count_2020_WDay, nos proposrciona que de la columna “week_day” tenemos las cantidades de “domingo” = 50850 ; “lunes” = 66778; “mates” = 74961; “miercoles” = 69911; “jueves”= 66140; “viernes” = 60663; “sabado”= 37584 Nos indica que entre semana hay mas uso siendo el dia martes el mas alto

Estructura

str(Count_2020_WDay)
## tibble [7 × 2] (S3: tbl_df/tbl/data.frame)
##  $ week_day: chr [1:7] "martes" "miércoles" "lunes" "jueves" ...
##  $ n       : int [1:7] 74961 69911 66778 66140 60663 50850 37584

Visual

View(Count_2020_WDay)

Seleccionamos tabla Count_2020_WDay que contiene los datos, pero al ver su estructura de la columna week_day es character y se cambiara a factor, permite que se pueda manipular los datos. levels es el argumento del constructor factor() que define qué categorías existen y en qué orden.

Count_2020_WDay$week_day<-factor( Count_2020_WDay$week_day,
                                  levels=Count_2020_WDay$week_day)

Ahora se realizara la creacion de una nueva columna en tabla Count_2019_WDay, para obtener porcentaje, una columna nueva llamada “percent”con dos decimales.

Count_2020_WDay <- Count_2020_WDay %>%
  mutate(percent=round(n/sum(n)*100,2))

Grafico denominado P12 para Uso de bicicleta por dia de la semana 2020

P12 <- ggplot(data = Count_2020_WDay , aes(x=week_day, y=n, fill = n ))+
geom_bar (stat = "identity")+
geom_text(aes(label=paste0(round(n,1), "\n (",round(percent,1),"%)"))
        # "\n Es el salto de linea 
          , vjust = -0.3 , size = 4 )+
expand_limits(y = max(Count_2020_WDay$n) * 1.15) +
 
  labs(title =  "Uso de Bicicletas por Dia de la Semana 2020",
       x= "Dia de la Semana", y = "Tiempo Recorrido por Dia ", 
       caption = "Data: Empresa Motivate International Inc\nP12")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Nota.-expand_limits:funcion que amplia un eje (x o y) sin cambiar datos (etiquetas)

Visual

P12

Tabla de usuarios por Estaciones 2020

Sel_User_Station_2020 <- Divvy_Trips_2020_Q1 [
  c("member_casual","start_station_id")]

Realizamos sumario de tabla Sel_User_Station_2020

summary(Sel_User_Station_2020)
##  member_casual      start_station_id
##  Length:426887      Min.   :  2.0   
##  Class :character   1st Qu.: 77.0   
##  Mode  :character   Median :176.0   
##                     Mean   :209.8   
##                     3rd Qu.:298.0   
##                     Max.   :675.0

Grafico Estaciones por Usuarios 2020 y su Densidad

P13<- ggplot(data = Sel_User_Station_2020,aes(x=start_station_id, 
                                              fill = member_casual ) )+
  geom_histogram(aes(y=after_stat(density)), binwidth = 5, position="dodge", 
                 color = "blue", alpha=0.6)+
  geom_density(aes( color = member_casual, linewidth = 1)) +
  facet_wrap(~ member_casual , nrow = 1)+
  labs( title = "Estaciones por Usuarios 2020",x = "Estaciones",y = "Densidad",
        caption = "Data: Empresa Motivate International Inc\nP13") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Visual

P13

2019 y 2020

Para realizar join, es decir la union de tablas, lo principal es que las variables o columnas de las tablas 2019 y 2020 tenga tipo de formato igual de tal manera que al unir en este las tablas se asegure un adecuado join. para ello veremos su tipos de formato por medio de la funcion str(). se incluye un cambio de nombre a cada tabla de manera que que no altere lo hecho anteriormente. Divvy_Trips_2019_Q1 = Join_2019 y Divvy_Trips_2020_Q1 = Join_2020 se realizara un “left_join()” que permite mantener las filas de la primera tabla Join_2019 y coincidentes con la tabla Join_2020.

Visualizacion de estructura de tipos de formatos en las tablas

Estructura

str(Divvy_Trips_2019_Q1)
## spc_tbl_ [365,069 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ trip_id          : chr [1:365069] "21742443" "21742444" "21742445" "21742446" ...
##  $ start_time       : POSIXct[1:365069], format: "2019-01-01 00:04:37" "2019-01-01 00:08:13" ...
##  $ end_time         : POSIXct[1:365069], format: "2019-01-01 00:11:07" "2019-01-01 00:15:34" ...
##  $ bikeid           : num [1:365069] 2167 4386 1524 252 1170 ...
##  $ tripduration     : num [1:365069] 390 441 829 1783 364 ...
##  $ from_station_id  : num [1:365069] 199 44 15 123 173 98 98 211 150 268 ...
##  $ from_station_name: chr [1:365069] "Wabash Ave & Grand Ave" "State St & Randolph St" "Racine Ave & 18th St" "California Ave & Milwaukee Ave" ...
##  $ to_station_id    : num [1:365069] 84 624 644 176 35 49 49 142 148 141 ...
##  $ to_station_name  : chr [1:365069] "Milwaukee Ave & Grand Ave" "Dearborn St & Van Buren St (*)" "Western Ave & Fillmore St (*)" "Clark St & Elm St" ...
##  $ usertype         : chr [1:365069] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ gender           : chr [1:365069] "Male" "Female" "Female" "Male" ...
##  $ birthyear        : num [1:365069] 1989 1990 1994 1993 1994 ...
##  $ ride_length      : 'difftime' num [1:365069] 390 441 829 1783 ...
##   ..- attr(*, "units")= chr "mins"
##  $ week_day         : chr [1:365069] "martes" "martes" "martes" "martes" ...
##  $ num_week_day     : num [1:365069] 3 3 3 3 3 3 3 3 3 3 ...
##  $ edad_cliente     : num [1:365069] 36 35 31 32 31 42 41 35 30 29 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Estructura

str(Divvy_Trips_2020_Q1)
## tibble [426,887 × 15] (S3: tbl_df/tbl/data.frame)
##  $ ride_id           : chr [1:426887] "EACB19130B0CDA4A" "8FED874C809DC021" "789F3C21E472CA96" "C9A388DAC6ABF313" ...
##  $ started_at        : POSIXct[1:426887], format: "2020-01-21 20:06:59" "2020-01-30 14:22:39" ...
##  $ ended_at          : POSIXct[1:426887], format: "2020-01-21 20:14:30" "2020-01-30 14:26:22" ...
##  $ start_station_name: chr [1:426887] "Western Ave & Leland Ave" "Clark St & Montrose Ave" "Broadway & Belmont Ave" "Clark St & Randolph St" ...
##  $ start_station_id  : num [1:426887] 239 234 296 51 66 212 96 96 212 38 ...
##  $ end_station_name  : chr [1:426887] "Clark St & Leland Ave" "Southport Ave & Irving Park Rd" "Wilton Ave & Belmont Ave" "Fairbanks Ct & Grand Ave" ...
##  $ end_station_id    : num [1:426887] 326 318 117 24 212 96 212 212 96 100 ...
##  $ start_lat         : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ start_lng         : num [1:426887] -87.7 -87.7 -87.6 -87.6 -87.6 ...
##  $ end_lat           : num [1:426887] 42 42 41.9 41.9 41.9 ...
##  $ end_lng           : num [1:426887] -87.7 -87.7 -87.7 -87.6 -87.6 ...
##  $ member_casual     : chr [1:426887] "member" "member" "member" "member" ...
##  $ ride_length       : 'difftime' num [1:426887] 451 223 171 529 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day          : chr [1:426887] "martes" "jueves" "jueves" "lunes" ...
##  $ num_week_day      : num [1:426887] 3 5 5 2 5 6 6 6 6 6 ...

Cambio de nombre a las tablas

Creacion de tabla Join_2019

Join_2019 <- Divvy_Trips_2019_Q1

Creacion de tabla Join_2020

Join_2020 <- Divvy_Trips_2020_Q1

En la tabla Join_2020 se encuentra la varible “member_casual” su filas contiene , tipo de cliente como “member” y ” “casual”, se le va a cambiar por sinonimos por “Subscriber” y “Customer” respectivamente, por medio de las funciones mutate(member_casual) y funcion recode()

Join_2020 <- Join_2020 %>%
  mutate(member_casual =recode(member_casual,
                            "member"= "Subscriber", "casual"= "Customer" ))

Diferencia entre años 2019 y 2020

Me interesa ver cual es la diferencia entre años y que porcentaje se incremento para dicho efecto contamos el numero de filas de cada tabla,

Numero de filas

n_Fi_2019 <- nrow(Join_2019)  

Numero de filas

n_Fi_2020 <- nrow(Join_2020)

Creacion de tabla con la funcion tibble()

Dif_Year <- tibble( Years= c("2019","2020"), n_Fi= c(n_Fi_2019,n_Fi_2020))

Diferencia de cantidades entra años 2019 y 2020 lag(n_Fi) obtiene el valor de Numero de Filas del registro anterior, permitiendo la resta para obtener la diferencia.

Calc_Dif <- Dif_Year %>%
  mutate(Dif =(n_Fi - lag(n_Fi)),
         percent= (Dif / lag(n_Fi))*100)

Para poder graficar, habia que cambiar los “N.A” por cero “0”, con el fin de que al graficar muestre valor cero y porcentaje cero del 2019. En ella usamos condicional con la funcion ifelse(), cambia con la funcion is.na() para valores “N.A” por “0” y no elimina la fila completa.

Calc_Dif <- Calc_Dif %>%
  mutate (Dif= ifelse(is.na(Dif),0,Dif))%>%
  mutate (percent= ifelse(is.na(percent),0,percent))

Grafico Diferencia de Clientes por año y Porcentaje 2019 y 2020

P14 <- ggplot(data=Calc_Dif, aes(x=Years, y=n_Fi, fill= Years))+
  geom_col()+
  geom_text(aes(label=paste0(n_Fi,"   " ,Dif, " (", round(percent,1),"%)"))
                     , vjust = -0.5)+
    scale_fill_manual(values = c("skyblue1","lightblue"))+ 
    labs(title= "Diferencia de Clietes por Year\nPorcentaje 2019 y 2020 ",
       x="Years", y="Cantidad de Registros",
       caption = "Data: Empresa Motivate International Inc\nP14")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Visual

P14

En el grafico P14, se puede visualizar, el incremento entre los años 2019 y 2020, es de 61818 corresponde año 2020 un 16.9 % mas que en el 2019. Cantidades en 2019 muestra cero, porque no hay año que antecede.

FUNCION JOIN

La funcion left_join() es la que se utilizara, porque mantiene todas las variables de la tabla Join_2019 para unir con la tabla Join_2020 a lo largo, antes de hacerlo y por recomendacion de expertos, lo mejor es crenomnbrar las variables Join_2020 y alinearlas con Join_2019 de, una manera# que permitira que no exista errores a futuro.

Join_2020<- Join_2020 %>%
  rename ( trip_id = ride_id ,  start_time = started_at,
                                end_time= ended_at,
                                usertype= member_casual,
                                from_station_id= start_station_id,
                                from_station_name = start_station_name,
                                to_station_id=end_station_id, 
                                to_station_name= end_station_name)

Ahora realizamos un left_join con el el fin de mantener todas las variables de join_2019 y las que coincidan con Join_2020, si es verdad muestra c_trip_id, se debe a que no coincide por tal motivo se muetra con N.A.

Join_Total<- left_join(Join_2019,Join_2020, by = "trip_id")

Visualiza

View(Join_Total)

Efectivamente junta las tablas de manera horizontal, sin embargo para el analisis, tenemos que realizar otros pasos adicionales y es la de juntar las variable tanto de la tabla Join_2019 y Join_2020 similares, para que muestre de manera vertical. Realizaremos un ejemplo con un fin practico. uniremos verticalmente las variables start_time.x con start_time.y, en una variable llamada start_time, con la funcion unite, adicionalmente, que nos omita todos los na.rm y que no nos remueva otras variables. Pondremos como nombre a la tabla Union_Join_Total

Union_Join_Total<- Join_Total %>%
  unite("start_time",start_time.x,start_time.y,
        remove = FALSE)

Visualizar

Union_Join_Total

Como podemos visualizar, no existe ninguna alteracion en la nueva columna y tampoco hay un aumento en la columna, debido que start_time.y en Join_Total no muestra datos.Por lo que se procedera con otra funcion llamada bind_rows() en lugar de left_join().

Uso de FUNCION bind_rows apilar tablas Join_2019 y Join_2020

Ahora utilizaremos la funcion bind_rows(), para apilar verticalmente la informacion, para el analisis usaremos las tablas Join_2019 y Join_2020, para este efecto. Pondremos de nombre una nueva tabla Union_Total.

Union_Total <- bind_rows(Join_2019,Join_2020)

Tablas y Graficos de Union Total

Ahora seleccionaremos las variables usertype y ride_length, para ello crearemos tabla llamada Sel_User_RidL_UTotal

Sel_User_RidL_UTotal <- Union_Total [c("usertype" , "ride_length")]

Sumario

summary(Sel_User_RidL_UTotal)
##    usertype          ride_length            
##  Length:791956      Min.   :     -552 secs  
##  Class :character   1st Qu.:      513 secs  
##  Mode  :character   Median :     1838 secs  
##                     Mean   :    28830 secs  
##                     3rd Qu.:    29220 secs  
##                     Max.   :637921320 secs

Realizamos su porcentaje de la tabla Sel_User_RidL_UTotal

Count_Sel_User_RidL_UTotal <- Sel_User_RidL_UTotal %>%
  count(usertype ) %>%
  mutate (percent = n/sum(n)*100)

Nota.-Argumento no numerico

Grafico P15 Tipo de Cliente pory su Porcentaje 2019 y 2020

P15 <- ggplot(data=Count_Sel_User_RidL_UTotal, aes(x=usertype, y=n, 
                                                 fill= usertype))+
  geom_col()+
  geom_text(aes(label=paste0(n, " (", round(percent,1),"%)"))
             , vjust = -0.5)+
   scale_fill_manual(values = c("skyblue1","lightblue"))+ 
   labs(title= "Tipo de Cliente por\nCantidad y su Porcentaje 2019 y 2020  ",
       x="Clientes", y="Cantidad",
       caption = "Data: Empresa Motivate International Inc\nP15")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Nota.-label=paste0. Se usa para concatenar, usando una cadena de caracteres vacios como separador.
Nota.-Utilizamos vjust=-0.5, para poner las etiqueta encima de las barras
Nota.-scale_fill_manual.Cambia los colores de relleno manualmente ya expuestos
Nota.-En la sentencia anterior centramos el titulo con la funcion hjust()

Visualizamos

P15

El grafico P15 nos da la visualizacion de la tabla Count_Sel_User_RidL_UTotal del Tipo de Cliente y su Porcentaje, en el nos muestra que “Subscriber” tiene 720313 con un 91%, mientras clientes “Customer” tiene 71643 con el 9%.

Tabla promedio agrupado por tipo de cliente para obtener la media

Main_Count_Sel_User_RidL_UTotal <- Sel_User_RidL_UTotal %>%
  group_by(usertype) %>%
  summarise(
    Mean_Rd_Length = as.numeric(mean(ride_length, na.rm = TRUE)))%>%
  mutate( percent = Mean_Rd_Length / sum(Mean_Rd_Length)*100 )

La Tabla muestra el resultado es que la trayectoria que recorren clientes “Customer” es de 222990.94, siendo un 81.7% mientras que los los clientes “Subscribes” es de 50014.33, siendo el 18.3% de tiempo recorrido por tipo de cliente, generamos un grafico para visualizar los datos, el que denominaremos P16

Creamos grafico denominado P16 de la tabla del Promedio del Tiempo y

clasificado por el Tipo Cliente.

P16 <- ggplot(data=Main_Count_Sel_User_RidL_UTotal, aes(x = usertype, 
                                      y = Mean_Rd_Length, fill = usertype)) +
geom_col() + geom_text(aes(label=paste0(round(Mean_Rd_Length,1), 
                                      " (",round(percent,1),"%)"))
            , vjust = -0.5)+
  scale_fill_manual(values = c("skyblue1","lightblue"))+ 
  labs(title =  "Tipo de Cliente por Tiempo Recorrido y\nPromedio en % 2019 y2020",
       x= "Clientes", y = "Promedio del Tiempo Recorrido", 
       caption = "Data: Empresa Motivate International Inc\nP16")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Nota.-# scale_fill_manual para asignacion manual de colores

Visual

P16

GRAFICOS PARALELOS P15 Y P16

Mostraremos como una especie de resumen con graficos paralelos P15 y P16 esta manera se puede comparar las graficas

(P15 + P16)+
  plot_annotation(
    title="DISTRIBUCION POR TIPO DE CLIENTE YEARS 2019 Y 2020",
    theme=theme(plot.title = element_text(hjust = 0.5)))

Dias de uso de bicicleta en la semana 2019 Y 2020

De la tabla Union_Total la columna “week_day” crea conteo de porque es tipo texto pondremos de nombre Count_Union_Total_WDay

Count_Union_Total_WDay<- Union_Total %>%
  count(week_day)

Ordenamos en forma descente de la variable “n” con la funcion arrange(desc())

Count_Union_Total_WDay<- Count_Union_Total_WDay %>%
  arrange(desc(n))

Posterior verificamos el resultado de Count_Union_Total_WDay, nos proposrciona que de la columna “week_day” tenemos las cantidades de “domingo” = 78849 ; “lunes” = 117177; “mates” = 135966; “miercoles” = 130325; “jueves”= 133043; “viernes” = 123710; “sabado”= 72886 Nos indica que entre semana hay mas uso siendo el dia martes el mas alto

Estructura

str(Count_Union_Total_WDay)
## spc_tbl_ [7 × 2] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ week_day: chr [1:7] "martes" "jueves" "miércoles" "viernes" ...
##  $ n       : int [1:7] 135966 133043 130325 123710 117177 78849 72886
##  - attr(*, "spec")=
##   .. cols(
##   ..   trip_id = col_double(),
##   ..   start_time = col_datetime(format = ""),
##   ..   end_time = col_datetime(format = ""),
##   ..   bikeid = col_double(),
##   ..   tripduration = col_number(),
##   ..   from_station_id = col_double(),
##   ..   from_station_name = col_character(),
##   ..   to_station_id = col_double(),
##   ..   to_station_name = col_character(),
##   ..   usertype = col_character(),
##   ..   gender = col_character(),
##   ..   birthyear = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Visual

View(Count_Union_Total_WDay)

Seleccionamos tabla Count_Union_Total_WDay que contiene los datos, para ver su estructura de la columna week_day es character y se cambiara a factor, permite que se pueda manipular los datos. levels es el argumento del constructor factor() que define qué categorías existen y en qué orden.

Count_Union_Total_WDay$week_day<-factor( Count_Union_Total_WDay$week_day,
                                  levels=Count_Union_Total_WDay$week_day)

Ahora se realizara la creacion de una nueva columna en tabla Count_Union_Total_WDay, para obtener porcentaje, una columna nueva llamada “percent”con dos decimales.

Count_Union_Total_WDay <- Count_Union_Total_WDay %>%
  mutate(percent=round(n/sum(n)*100,2))

Grafico denominado P17 para Uso de bicicleta por dia de la semana 2019 y 2020

P17 <- ggplot(data = Count_Union_Total_WDay , aes(x=week_day, y=n, fill = n ))+
  geom_bar (stat = "identity")+
  geom_text(aes(label=paste0(round(n,1), "\n (",round(percent,1),"%)"))
                        , vjust = -0.3 , size = 4 )+
  expand_limits(y = max(Count_Union_Total_WDay$n) * 1.15) +
    labs(title =  "Uso de Bicicletas por Dia de la Semana 2019 y 2020",
       x= "Dia de la Semana", y = "Tiempo Recorrido por Dia ", 
       caption = "Data: Empresa Motivate International Inc\nP17")+
  theme(plot.title = element_text(hjust = 0.5),legend.position = "none")

Nota.- expand_limits:funcion que amplia un eje (x o y) sin cambiar datos(etiquetas)

Visual

P17

Grafico denominado P18 segmentado por tipo de cliente

para uso de bicicleta por dia de la semana y porcentaje2019 y 2020

Seleccionamos variables usertype, ride_length,week_day, esta seleccion es para generar un grafico

Sel_User_RidL_Wd_UTotal <- Union_Total [c("usertype" ,"ride_length" ,"week_day")]

Vemos su estructura

str(Sel_User_RidL_Wd_UTotal)
## tibble [791,956 × 3] (S3: tbl_df/tbl/data.frame)
##  $ usertype   : chr [1:791956] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ ride_length: 'difftime' num [1:791956] 23400 26460 49740 106980 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day   : chr [1:791956] "martes" "martes" "martes" "martes" ...

Se visualiza que la variable week_day, no contenga tildes con la funcion unique()

unique(Sel_User_RidL_Wd_UTotal$week_day)
## [1] "martes"    "miércoles" "jueves"    "viernes"   "sábado"    "domingo"  
## [7] "lunes"

Al ver que tiene tildes realice otras maneras me generaba N.A. y eliminaba asi que acudi y agradezco a la IA que me dio una solucion efectiva para los dias sabado y miercoles, por tal razo se utiliza sentencia que no genera N.A. en registros.

Sel_User_RidL_Wd_UTotal <- Sel_User_RidL_Wd_UTotal %>%
  mutate(
    week_day = iconv(week_day, from = "UTF-8", to = "ASCII//TRANSLIT"))

Verficamos que la variable week_day, no contenga tildes con la funcion unique()

unique(Sel_User_RidL_Wd_UTotal$week_day)
## [1] "martes"    "miercoles" "jueves"    "viernes"   "sabado"    "domingo"  
## [7] "lunes"

Vemos su estructura

str(Sel_User_RidL_Wd_UTotal)
## tibble [791,956 × 3] (S3: tbl_df/tbl/data.frame)
##  $ usertype   : chr [1:791956] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ ride_length: 'difftime' num [1:791956] 23400 26460 49740 106980 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day   : chr [1:791956] "martes" "martes" "martes" "martes" ...

Para operar la tabla en el calculos o grafico ,se necesita cambiar de la tabla Sel_User_RidL_Wd_UTotal, la variable week_day, que es tipo caracter la transformamos a Factor por ser un listado fijo de los dias de la semana. Usamos la funcion unique porque los dias de la semana se repite

Sel_User_RidL_Wd_UTotal$week_day<-factor( Sel_User_RidL_Wd_UTotal$week_day,
                              levels=unique(Sel_User_RidL_Wd_UTotal$week_day))

Nuevamente vemos su estructura

str(Sel_User_RidL_Wd_UTotal)
## tibble [791,956 × 3] (S3: tbl_df/tbl/data.frame)
##  $ usertype   : chr [1:791956] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ ride_length: 'difftime' num [1:791956] 23400 26460 49740 106980 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day   : Factor w/ 7 levels "martes","miercoles",..: 1 1 1 1 1 1 1 1 1 1 ...

Posterior en la misma tabla genera una nueva variable a partir de la variable ride_length, que tiene tipo de formato de tiempo difftime, esta crea una nueva variable denominada ride_length_sec y tambien la convierte en tipo de formato numerico, esto ayuda para que creamos grafico sin dificultad.

Sel_User_RidL_Wd_UTotal<- Sel_User_RidL_Wd_UTotal%>%
  mutate(ride_length_sec = as.numeric(ride_length, units="secs"))

Verificamos

str(Sel_User_RidL_Wd_UTotal)
## tibble [791,956 × 4] (S3: tbl_df/tbl/data.frame)
##  $ usertype       : chr [1:791956] "Subscriber" "Subscriber" "Subscriber" "Subscriber" ...
##  $ ride_length    : 'difftime' num [1:791956] 23400 26460 49740 106980 ...
##   ..- attr(*, "units")= chr "secs"
##  $ week_day       : Factor w/ 7 levels "martes","miercoles",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ ride_length_sec: num [1:791956] 23400 26460 49740 106980 21840 ...

Limpiamos valores invalidos, porque se visualizo valores negativos y no tiene sentido el uso de tiempo de manera negativa, en el caso que exista y cambiamos de nombre a la tabla Sel_User_RidL_Wd_UTotal_Limpio de manera que funcione adecuadamente el para posteriores calculos y grafico

Sel_User_RidL_Wd_UTotal_Limpio<- Sel_User_RidL_Wd_UTotal%>%
  filter(ride_length >0 )

Realizamos el calculo de la media de tiempo de viaje, creando un group_by de variables usertype con week_day para sacar el promedio de la variable ride_length. Usamos la funcion drop se usa para eliminar (descartar) niveles, dimensiones o grupos que ya no # se necesita, es decir elimina el group_by luego de resumir.

Media_RidL <- Sel_User_RidL_Wd_UTotal_Limpio %>%
  group_by(usertype, week_day) %>%
  summarise(media_ridl = mean(ride_length_sec, na.rm = TRUE), .groups = "drop")

Visual

View(Media_RidL)

Necesito crear otra tabla que me permita calcular el promedio de cada dia, que aporta cada cliente “usertype”y de la variable Week_day, para ello agrupamos momentaneamente y utilizaremos valores de la anterior tabla. Se realiza el calculo asi, porque son factores tipo texto su porcentaje se lo realiza de esta manera , porque es texto o factor. el siguiente calculo barca los valores de la otra tabla y genera promedio diario por tipo cliente

Media_RidL_WDay <- Media_RidL %>%
  group_by(week_day) %>%
  mutate(percent=media_ridl/sum(media_ridl)*100) %>%
  ungroup()

Visual

View(Media_RidL_WDay)

Generamos grafico P18 de Duracion Promedio de Viaje por Dia y Tipo de Cliente 2019 y 2020

P18<-ggplot(Media_RidL_WDay,
       aes(x = week_day, y = media_ridl, fill = usertype)) +
  geom_col(position = "dodge", width = 0.9) +
  geom_text(aes(label = paste0(round(media_ridl,0),"\n(", round(percent, 1), "%)")),
  position = position_dodge(width = 0.9), vjust =0, size = 2)+          
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Duracion Promedio de Viaje por Dia y Tipo de Cliente 2019 y 2020",
    x = "Dia de la Semana",
    y = "Duracion Promedio (segundos)",
    fill = "Tipo de Cliente",
    caption = "Data: Empresa Motivate International Inc\nP18")+
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Visual

P18

ANALISIS RStudio

Este apartado se centra en los factores relevantes del proceso, en el que resolvemos la pregunta principal del caso de estudio de la empresa Cyclistic Cuál es el problema que estás tratando de resolver?

Su Gerente y Directora de marketing, tiene mucha experiencia en el programa Cyclistic, y se respaldado de su equipo de trabajo en el que me incluyo, su labor y perseverancia en las campañas a traves de redes sociales ha dado beneficios, y desea continuar manteniendo con campañas de, para que los clientes casuales sean miembros permanentes del programa Cyclistic.

Para ello presento algunos motivos. Rodando por datos que le puede ayudar a su capaña durante los cuartiles de los años 2019 y 2020 visualice que Tipo de Clientes con su Porcentaje, muestra que “Miembros” permanentes son 720313 que correspondes aun 91%, mientras clientes “Casuales” tiene 71643 con el 9%. Podemos visualizar en la siguiente tabla

Count_Sel_User_RidL_UTotal

Rodando por el grafico de la tabla anterior, el 90.95% han decidido ser “Miembros”, ese particular se presenta porque el paquete para ser “Miembros” anual, es mucho mas economico en el tiempo, que un paquete individual, lo mas interesante es que las campañas en redes sociales han sido esitosas, comprende el cliente que le favorece ser cliente permanente del proyecto Cyclistic, veamos en el grafico

P15

Sigamos rodando y vemos la trayectoria de recorrido, los datos muestra que en esos mismos periodos, muestra el resultado en la trayectoria que recorren clientes “Casuales” es de 4329619.9, siendo un 75.2% mientras que clientes “Miembros” es de 1424797, es el 24.8% de tiempo recorrido. Visualizamos en el grafico siguiente.

Main_Count_Sel_User_RidL_UTotal

El 75.9% de clientes “Casuales” han recorrido mayores distancias en promedio, este particular, es porque la mayor parte de los clientes de edades que estudian o laboran medio tiempo.

P16

Continuamos rodando por el siguiente grafico que corresponde solo al año 2019, la informacion que presenta es difiere con la que existe en el 2020, pero el año 2019 muestra que la densidad es decir la cantidad de clientes por edad esta a la izquierda de la media, es decir que va desde los 20 años hasta los 43 años, es el pico del grafico, no imoprta su genero, porque es similar su promedio. Esto ratifica lo que se expuso, anteriormente, que las distancias recorridas son justamente personas que estudian o laboran mediotiempo.

P8

Hacemos un parada, porque se presenta una situacion interesante que en fin de semana que disminuye el numero de clientes en el uso de bicicletas lo podemos visualizar en el siguiente grafico. Observemos que entre semana de lunes a viernes la movilizacion de los clientes en bicicletas compartidas es mayor que los fines de semana, por lo que se ratica que los clientes o estudian o trabajan

Visual

P17

Podemos ver la tabla en que los clientes en recorren en promedio bicicletas compartidas por dia

Media_RidL_WDay

La tabla nos muestra el tipo d clientes (usertype), por dia (week_day) y en cifras la media por viaje en valor (media_ridl) y su porcentaje diario (percent) vemos que los clientes “casual” o “Customer” el dia domingo viaja en promedio 34782.59 segundos, que corresponde un 58.26% del que clientes “members” o “Subscriber” que viaja 24913.14 segundos; el dia juves los clientes “casual” viaja en promedio 185740.46 segundos con un 89.22%, mientra que el mismo dia los “member” viaja con un promedio de 22429.33 segundos con un 10.77% ; los dias lunes los clientes “casual” viaja en promedio 48450.25 segundos con un 67.26%, mientras que los”member” viaja en un promedio de 23578.59 corresponde un 32.73% ; los dias marte los clientes “casual” recorren 53189.96 segundos con un porcentaje del 68.97%, mientras que “member realizan 23929.78 con 31.02% ; los miercoles los”casual”recorre 58861.01 segundo, que corresponde 73.65% en contraste que clientes “member” recorre 21057.68 segundos con un porcentaje de 26.34% ; dia sabado recorren en promedio 99948.99 que representa un 76.53% y “member” recorren 30642.59 segundos con un porcentaje del 23.46% ; por ultimo los dias viernes los clientes “casual” viaja en promedio un 89842.03 segundo con un 77.37% mientra que “member” el mismo dia viaja 26273.05 segundos con un 22.62%

Tenemos una vista cuando se esta rodando del grafico que esta segmentado por tipo de cliente y su porcentaje por dia de la semana

Visual

P18

Como podemos ver los clientes a pesar de que en cantidad de clientes “casual” o tambien llamados “Customer” son menores, pero el recorrido diario es superior casi en doble de viajes diarios que los “Member” tambien llamados “Suscriber” y lo mas interseante es que su mayor trayecto en dias laborables, lo que descarta que sean, que en el grafico P17 sean turistas, como lo habiamos mensionado anterioremente, mas bien son residentes de la ciudad d Chicago. Ademas sirve para ver que dias se realiza un tipo de campaña por redes sociales.

Para completar vemos la cantidad de clientes por cada año y su diferencia y porcentaje

Calc_Dif

En el años 2019 habia 365069 y en el años 2020 existieron 426887, su diferencia es de 61818 usarios lo que corresponde un 16.93% de incremnto de clientes que ruedan en biclicletas compartidas de la empresa Cyclistic. Podemos verlo en el siguiente grafico

Visual

P14

Rodando por el grafico vemos que sus datos tiene un crecimiento anual en el 2020 del 16.9% con relacion a 2019, es bastante significativo, ya que podriamos comparar con la economia general que esta alrededor del 4% anual de crecimiento, eso indica que el programa Cyclistic esta consolidado, su Gerente y Directora de Marketing , continuara generando conciencia el uso de bicicletas compartidas.

RECOMENDACION

Ahora que hemos concluido de rutear en el analisis, la Gerente y Directora de Marketing, considerara la informacion extraida y tomara mejor su decision, sin antes de recomendarle, que de acuerdo a los datos, podemos sugerir que la campaña que ella propone, sea dirigida a Clientes “Casuales” , que estudian o laboran, entre semana. Para que continuen rodando y generando conciencia sobre la salud y bienestar ambiental, el programa de Cyclistic es un gran aliado.