1. Descripción del archivo de datos

La data que seleccioné para analizar para esta practica del foro fue la de las transacciones con tarjetas de créditos. El archivo de datos a utilizar, de nombre credit_card_transaction_flow.csv, es un data.frame. Se trata de un archivo multivariable, con 50,000 observaciones y obtenido del la web <a href=“https://www.kaggle.com/datasets/rajatsurana979/comprehensive-credit-card-transactions-dataset”

La base de datos cuentas con las siguientes variables:

  • Customer ID: Identificador unico por cada cliente.
  • Name: Primer nombre del cliente.
  • Surname: Primer apellido del cliente.
  • Gender: Genero del cliente.
  • Birthdate: Fecha de nacimiento de cada cliente.
  • Tansaction Amount: El monto en dólares de cada transacción.
  • Date: Fecha en la que se produjo la transacción.
  • Merchant Name: El nombre del comerciante donde se realizó la transacción.
  • Category: Categorización de la transacción.

2. Selección

Con esta elección busco explorar un poco los hábitos de consumos de los clientes en un periodo de tiempo, analizando algunas variables cuantitativas a través de tablas de frecuencias, medidas numéricas y distintos de gráficos.

3. Instalación de las librerías necesarias

library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.4
## ✔ ggplot2   3.4.4     ✔ stringr   1.5.0
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ── 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
library(modeest)
## Warning: package 'modeest' was built under R version 4.3.2
library(moments)
## 
## Attaching package: 'moments'
## 
## The following object is masked from 'package:modeest':
## 
##     skewness
library(ggplot2)
library(nortest)
library(lubridate)
library(car)
## Warning: package 'car' was built under R version 4.3.2
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.3.2
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:purrr':
## 
##     some
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
library(fastDummies)
## Warning: package 'fastDummies' was built under R version 4.3.2
## Thank you for using fastDummies!
## To acknowledge our work, please cite the package:
## Kaplan, J. & Schlegel, B. (2023). fastDummies: Fast Creation of Dummy (Binary) Columns and Rows from Categorical Variables. Version 1.7.1. URL: https://github.com/jacobkap/fastDummies, https://jacobkap.github.io/fastDummies/.

4. Estadística descriptiva de variables

4.1 Ambiente de trabajo

getwd()
## [1] "C:/Users/bianc/OneDrive/Escritorio/Maestria/Modulo 2/Foro"
setwd("C:/Users/bianc/OneDrive/Escritorio/Maestria/Modulo 2/Foro")
Credit_transaction=read.csv("credit_card_transaction_flow.csv", sep=",", header=TRUE)

4.2 Características generales de la base de datos

Observación de la base de datos Credit Transaction

dim(Credit_transaction) #Dimención de la base de datos, filas y columnas de forma conjunta
## [1] 50000     9
names(Credit_transaction) #Nombre de las variables
## [1] "Customer.ID"        "Name"               "Surname"           
## [4] "Gender"             "Birthdate"          "Transaction.Amount"
## [7] "Date"               "Merchant.Name"      "Category"
nrow(Credit_transaction) # Número de filas
## [1] 50000
head(Credit_transaction, n=10) #Primera filas de la base de datos Credit Transaction
##    Customer.ID      Name    Surname Gender  Birthdate Transaction.Amount
## 1       752858      Sean  Rodriguez      F 20-10-2002              35.47
## 2        26381  Michelle     Phelps        24-10-1985            2552.72
## 3       305449     Jacob   Williams      M 25-10-1981             115.97
## 4       988259    Nathan     Snyder      M 26-10-1977              11.31
## 5       764762   Crystal      Knapp      F 02-11-1951              62.21
## 6       576539    Monica   Bartlett      F 20-10-2001              99.14
## 7       124681    Thomas       Shaw        26-10-1976             145.94
## 8       521807    Kelsey       Pena      F 28-10-1968             161.39
## 9       504238    Denise     Porter      M 31-10-1957              77.73
## 10      583532 Alexander Richardson      F 27-10-1974             142.85
##          Date              Merchant.Name    Category
## 1  03-04-2023              Smith-Russell    Cosmetic
## 2  17-07-2023     Peck, Spence and Young      Travel
## 3  20-09-2023                 Steele Inc    Clothing
## 4  11-01-2023 Wilson, Wilson and Russell    Cosmetic
## 5  13-06-2023              Palmer-Hinton Electronics
## 6  24-08-2023     Tran, Torres and Joyce    Cosmetic
## 7  30-08-2023  Evans, Griffin and Torres    Cosmetic
## 8  08-02-2023                 Miller PLC    Cosmetic
## 9  12-01-2023             Jackson-Morgan  Restaurant
## 10 07-06-2023   Blake, Mays and Anderson    Clothing
sum(is.na(Credit_transaction))# Si contienen n/a o no
## [1] 0
str(Credit_transaction) #Estructura de la base de datos
## 'data.frame':    50000 obs. of  9 variables:
##  $ Customer.ID       : int  752858 26381 305449 988259 764762 576539 124681 521807 504238 583532 ...
##  $ Name              : chr  "Sean" "Michelle" "Jacob" "Nathan" ...
##  $ Surname           : chr  "Rodriguez" "Phelps" "Williams" "Snyder" ...
##  $ Gender            : chr  "F" "" "M" "M" ...
##  $ Birthdate         : chr  "20-10-2002" "24-10-1985" "25-10-1981" "26-10-1977" ...
##  $ Transaction.Amount: num  35.5 2552.7 116 11.3 62.2 ...
##  $ Date              : chr  "03-04-2023" "17-07-2023" "20-09-2023" "11-01-2023" ...
##  $ Merchant.Name     : chr  "Smith-Russell" "Peck, Spence and Young" "Steele Inc" "Wilson, Wilson and Russell" ...
##  $ Category          : chr  "Cosmetic" "Travel" "Clothing" "Cosmetic" ...

4.3 Tabla de Frecuencias agrupadas

#El nombre de la función será tdfA. 
#Los datos deben de estar guardados en un vector y
tdfA <- function(y) 
  {
  #Calculamos el número de clases usando la Regla de Sturges  
  k <- nclass.Sturges(y)
  #Formamos los intervalos de clase. Fijaros que k hace referencia a la "misma" amplitud del intervalo.
  intervalos <- cut(y, breaks = k)
  #Tabla de frecuencias absolutas
  tabla2 <- as.data.frame(table(intervalos))
  #Añadimos frecuencias acumuladas y frecuencias relativas
  tabla2 <- transform(tabla2, F.Acum = cumsum(Freq), F.R = prop.table(Freq))
  #Añadimos frecuencias relativas acumuladas
  tabla2 <- transform(tabla2, F.R.Acum = cumsum(F.R))
  #Multiplicamos las frecuencas relativas por 100
  tabla2 <- transform(tabla2, FR.Porc = 100*F.R, FRA.Porc = 100*F.R.Acum)
  #Para obtener las marcas de clase, usaremos:  
  midpoints <- function(x, dp=2)
    {
    lower <- as.numeric(gsub(',.*','',gsub('\\(|\\[|\\)|\\]','', x)))
    upper <- as.numeric(gsub('.*,','',gsub('\\(|\\[|\\)|\\]','', x)))
    return(round(lower+(upper-lower)/2, dp))
    }
  #Por último, agregamos la columna marcas de clase 
  tabla2 <- transform(tabla2, MC = midpoints(intervalos))
  tabla2
  }
tdfA(Credit_transaction$Transaction.Amount)
##             intervalos  Freq F.Acum     F.R F.R.Acum FR.Porc FRA.Porc      MC
## 1           (2.02,181] 24900  24900 0.49800  0.49800  49.800   49.800   91.51
## 2            (181,357]  9267  34167 0.18534  0.68334  18.534   68.334  269.00
## 3            (357,534]  4594  38761 0.09188  0.77522   9.188   77.522  445.50
## 4            (534,710]  2071  40832 0.04142  0.81664   4.142   81.664  622.00
## 5            (710,886]  2026  42858 0.04052  0.85716   4.052   85.716  798.00
## 6       (886,1.06e+03]  1529  44387 0.03058  0.88774   3.058   88.774  973.00
## 7  (1.06e+03,1.24e+03]   532  44919 0.01064  0.89838   1.064   89.838 1150.00
## 8  (1.24e+03,1.41e+03]   546  45465 0.01092  0.90930   1.092   90.930 1325.00
## 9  (1.41e+03,1.59e+03]   509  45974 0.01018  0.91948   1.018   91.948 1500.00
## 10 (1.59e+03,1.77e+03]   486  46460 0.00972  0.92920   0.972   92.920 1680.00
## 11 (1.77e+03,1.94e+03]   525  46985 0.01050  0.93970   1.050   93.970 1855.00
## 12 (1.94e+03,2.12e+03]   560  47545 0.01120  0.95090   1.120   95.090 2030.00
## 13  (2.12e+03,2.3e+03]   502  48047 0.01004  0.96094   1.004   96.094 2210.00
## 14  (2.3e+03,2.47e+03]   469  48516 0.00938  0.97032   0.938   97.032 2385.00
## 15 (2.47e+03,2.65e+03]   520  49036 0.01040  0.98072   1.040   98.072 2560.00
## 16 (2.65e+03,2.82e+03]   497  49533 0.00994  0.99066   0.994   99.066 2735.00
## 17    (2.82e+03,3e+03]   467  50000 0.00934  1.00000   0.934  100.000 2910.00

4.4. Medidas numéricas de la variable Transaction.Amount

Se calcularon algunas medidadas de dispersión sobre la variable Transaction.Amount. La desviación estándar nos indica que existe una dispersión de US$631 respecto a la media de US$442.

var(Credit_transaction$Transaction.Amount)
## [1] 399006.6
sd(Credit_transaction$Transaction.Amount)
## [1] 631.6697
summary(Credit_transaction$Transaction.Amount)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    5.01   79.01  182.19  442.12  470.51 2999.88

4.4.1. Medidas de forma

skewness(Credit_transaction$Transaction.Amount,na.rm = TRUE)
## [1] 2.30694

Según el resultado obtenido por el coeficiente de asimetría Fisher, se trata de una asimetría positiva a la derecha (CAF>0).

kurtosis(Credit_transaction$Transaction.Amount)
## [1] 7.76428

La distribución de los datos de la variable Transaction.Amount presenta una asimetría positiva y un apuntamiento (leptocúrtica), lo que supone que hay una gran cantidad de datos cercanos a la media.

4.5 Histograma

hist(Credit_transaction$Transaction.Amount,main="Histograma de la variable Transaction.Amount", xlab="Transaction.Amount",ylab="frequencia", col="light blue")

El histograma de la variable Transaction.Amount nos confirma que la distribución de los datos tiene una asimetría positiva. Que es igual a una distribución unimodal asimétrico a la derecha.

4.6 Boxplot

boxplot(Credit_transaction$Transaction.Amount, col="light blue")

El el boxplot y el histograma se observa que hay muchas transansaciones concentradas en valores pequeños. Para tratar de normalizar la data use la expresión Ln(X).

TA_transformada=log(Credit_transaction$Transaction.Amount)
hist(TA_transformada, main="Histograma de la variable Transaction.Amount transformada", xlab="Transaction.Amount",ylab="frequencia", col="light blue")
lines(density(TA_transformada))

Con la transformación de la variable Transaction.Amount se consiguió que los datos se acerquen más a la distribución normal. Sin embargo, no se logro que los valores se concentraran más en la media.

4.7 Correlación

La primera correlación que realice con la variable Transaction.Amount fue con la variable Gender. A la variable Gender tuve que crear variable dummies para poder convertilar en variable cuantitativa y poder generar la correlación.

Credit_transaction$Femenino <- ifelse (Credit_transaction$Gender== "F" ,1, 0)
CorrelaciónF<- cor(Credit_transaction$Femenino,log(Credit_transaction$Transaction.Amount))
print (CorrelaciónF)
## [1] 0.002234096
Credit_transaction$Masculino <- ifelse (Credit_transaction$Gender== "M" ,1, 0)
CorrelaciónM<- cor(Credit_transaction$Masculino,log(Credit_transaction$Transaction.Amount))
print (CorrelaciónM)
## [1] 0.001631236

Ambas variables tienen correlación positivas con respecto a la Transaction.Amount pero dicha correlación es debil en ambas.La mayor correlación se puede apreciar en el sexo femenino.

La segunda correlacion fue entre la variable Transaction.Amount y Category. Para la variable Category cree variables dummies para poder correlacionarlas.

Credit_transaction <-dummy_cols(Credit_transaction, select_columns = c("Category"))
CorrelaciónC<- cor(Credit_transaction[,12:17],log(Credit_transaction$Transaction.Amount))
CorrelaciónC
##                               [,1]
## Category_Clothing    -0.1344703724
## Category_Cosmetic    -0.2790959238
## Category_Electronics  0.2725717805
## Category_Market      -0.0006474889
## Category_Restaurant  -0.4969091304
## Category_Travel       0.6375488962

Solo las categorías Electronics y Travel tienen una correlación positiva con la variable Transaction.Amount, las demás tienen correlación negativa, siendo la categoría market con la correlación negativa más debil y la de travel con correlación positiva más fuerte.

5. Modelo de regresión de la variable Transaction.Amount

Modelo<- lm (log(Credit_transaction$Transaction.Amount)~as.factor(Category),Credit_transaction)
summary (Modelo)
## 
## Call:
## lm(formula = log(Credit_transaction$Transaction.Amount) ~ as.factor(Category), 
##     data = Credit_transaction)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.6725 -0.3982  0.2002  0.5676  0.9306 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                     4.896102   0.007951  615.79   <2e-16 ***
## as.factor(Category)Cosmetic    -0.420158   0.011251  -37.35   <2e-16 ***
## as.factor(Category)Electronics  1.175952   0.011223  104.78   <2e-16 ***
## as.factor(Category)Market       0.387813   0.011204   34.62   <2e-16 ***
## as.factor(Category)Restaurant  -1.034620   0.011193  -92.43   <2e-16 ***
## as.factor(Category)Travel       2.221797   0.011205  198.28   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.7227 on 49994 degrees of freedom
## Multiple R-squared:  0.6858, Adjusted R-squared:  0.6858 
## F-statistic: 2.183e+04 on 5 and 49994 DF,  p-value: < 2.2e-16

Todas las variables del modelo son significativas al 1%, con un R-cuadro ajustado al 68.5%. Las transaciones de la categoría travel son en promedio 9 veces mayores que cuando se tratan de las transacciones de la categoría clothing.

En la gráfica de bloxplot podemos apreciar mejor los datos extaridos del modelo.En la gráfica se puede apreciar claramente como el promedio de las transaciones con tarjeta de creditos en la categoría travel son superiores a todas las categorías incluyendo la de clothing.

CTday= Credit_transaction %>%
  mutate(DayW=as.factor(wday(Date, week_start = 1)))
ggplot(data =CTday)+
  geom_boxplot(aes(y=log(Transaction.Amount),col=Category), alpha = 0.5)+
  theme_classic()

## 6. Análisis de la variable Gender

En la base de datos Credit_transaction hay más mujeres que hombres equivalentes a 22,713 y 22,240, respectivamente. Por igual, la variable Gender tiene valores sin clasificación, ha estos los llame NA. Atendiendo a lo antes mencionado se esperaría que las transacciones por mujeres deberían ser mayor a la de los hombres, sin embargo, el gráfico de cajas nos muestra que el promedio de transacciones es muy parecido entre hombre y mujeres. No obstante, si hacemos una suma de los montos de transacción si podemos ver que en general las mujeres gastan un poco más que los hombres.

Credit_transaction <- Credit_transaction %>%
  mutate(Gender1 = ifelse(Gender == "","NA",Gender))

Credit_transaction %>%
  count(Gender1)
##   Gender1     n
## 1       F 22713
## 2       M 22240
## 3      NA  5047
ggplot(data =Credit_transaction)+
  geom_boxplot(aes(y=log(Transaction.Amount),col=Gender1), alpha = 0.5)+
  theme_classic()

Credit_transaction %>%
  group_by(Gender1) %>% summarise(Monto=sum(Transaction.Amount))
## # A tibble: 3 × 2
##   Gender1     Monto
##   <chr>       <dbl>
## 1 F       10119120.
## 2 M        9794883.
## 3 NA       2191959.

La categoría Travel es donde más gastan tanto hombre como mujeres. Sin embargo, las mujeres consumen más que los hombres en Travel, US$ 318,657.39 más que el género masculino. En adición, las mujeres consumen más en Cosmetic y Restaurant. Sin embargo, los hombres consumen más en Electronics, Market y Clothing. Siendo Electronics el que más consumo presenta con relación al género femenino.

En el gráfico de cajas se puede observar que los consumos son muy parecidos entre los generos. Mientras que en la tabla si podemos observar la diferencia en el monto gastado por genero en las diferentes categorías.

ggplot(Credit_transaction, aes(x =Category , y = log(Transaction.Amount) , col = Gender1)) +
  geom_boxplot() + labs(x = "Category", y = "Value", fill = "Gender")

TablaGender = Credit_transaction %>% 
  group_by(Gender1, Category) %>% 
  summarise( Sum =sum(Transaction.Amount),
             Mean = mean(Transaction.Amount))
## `summarise()` has grouped output by 'Gender1'. You can override using the
## `.groups` argument.
TablaGender
## # A tibble: 18 × 4
## # Groups:   Gender1 [3]
##    Gender1 Category         Sum   Mean
##    <chr>   <chr>          <dbl>  <dbl>
##  1 F       Clothing     587939.  161. 
##  2 F       Cosmetic     407488.  107. 
##  3 F       Electronics 1977312   521. 
##  4 F       Market       959850.  257. 
##  5 F       Restaurant   211186.   55.1
##  6 F       Travel      5975347. 1548. 
##  7 M       Clothing     594995.  159. 
##  8 M       Cosmetic     383399.  106. 
##  9 M       Electronics 1994009.  533. 
## 10 M       Market       960421.  256. 
## 11 M       Restaurant   205371.   55.6
## 12 M       Travel      5656689. 1528. 
## 13 NA      Clothing     136409.  159. 
## 14 NA      Cosmetic      85786.  107. 
## 15 NA      Electronics  422771.  535. 
## 16 NA      Market       230864.  258. 
## 17 NA      Restaurant    47932.   54.1
## 18 NA      Travel      1268196. 1558.