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:
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.
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/.
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)
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" ...
#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
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
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.
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.
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.
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.
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.