Čistenie údajov

Tu sa v názvoch stĺpcov vyskytujú medzery. Názvy stĺpcov sa v prostredí R stávajú názvami premenných a tie nesmú byť súčasťou názvu premennej. Neprípustné znaky v názvoch premenných vo všeobecnosti môžeme nahradiť s pomocou knižnice janitor.

Import údajov

Skontrolujeme si, či sa doplňujú na miesta chýbajúcich údajov doplňujú NA hodnoty (NA - Not Available).

# Import the CSV file into a data frame
# - header = TRUE: the first row contains variable names
# - sep = ";": variables are separated by semicolons
# - dec = ".": decimal numbers use a dot
# - na.strings = c("", "NA"): empty cells and text "NA" are treated as missing values
# - stringsAsFactors = FALSE: text variables remain text, not factors
setwd("D:/reposit/11955973")
udaje1 <- read.csv2(
  "imputacia/udaje/ChybnaDatabaza.csv",
  header = TRUE,
  sep = ";",
  dec = ".",
  na.strings = c("", "NA"),
  stringsAsFactors = FALSE
)
log_data <- read.csv("smart_logistics_dataset.csv")
names(log_data) <- tolower(names(log_data))
names(log_data) <- gsub(" ", "_", names(log_data))
# Show the first rows of the dataset

head(udaje1)

Upravovanie názvov premenných

# Load the dplyr package
# dplyr provides convenient tools for working with data frames
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(mice)
## 
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
## 
##     filter
## The following objects are masked from 'package:base':
## 
##     cbind, rbind
# -----------------------------
# 1. Save the original column names
# -----------------------------
old_names <- names(udaje1)

# -----------------------------
# 2. Shorten (abbreviate) column names
# -----------------------------
# rename_with() applies a function to all column names
# abbreviate() automatically shortens long names
# strict = FALSE allows a more flexible abbreviation
udaje1 <- udaje1 %>%
  rename_with(~ abbreviate(.x, strict = FALSE))

# -----------------------------
# 3. Ensure that column names are unique
# -----------------------------
# Sometimes abbreviation may create identical names
# make.unique() automatically adds suffixes (.1, .2, ...) if necessary
names(udaje1) <- make.unique(names(udaje1))

# -----------------------------
# 4. Show comparison: old vs. new names
# -----------------------------
comparison <- data.frame(
  Original_Name = old_names,
  Shortened_Name = names(udaje1)
)

print(comparison)
##                     Original_Name Shortened_Name
## 1                           YEARS           YEAR
## 2                       COMPANIES           COMP
## 3                 EXCHANGE.SECTOR           EXCH
## 4                PRIMARY.BUSINESS           PRIM
## 5                         TOBIN.Q           TOBI
## 6           MARKET.CAPITALIZATION           MARK
## 7                RETURN.ON.ASSETS           RETU
## 8                   DEBT.TO.ASSET           DEBT
## 9                       FIRM.SIZE           FIRM
## 10        SOCIAL.DISCLOSURE.INDEX           SOCI
## 11 ENVIRONMENTAL.DISCLOSURE.INDEX           ENVI
## 12    GOVERNANCE.DISCLOSURE.INDEX           GOVE
## 13                      ESG.INDEX           ESG.

Počiatočné čistenie obsahu databázy, imputácia chýbahúcich údajov

Odporúčam tu použiť knižnice VIM, Amelia, mice a iné. Pokiaľ máme databázu dostatočne nekonzistentnú a nevieme ju upraviť vynechaním niekoľkých riadkov / stĺpcov, potom odporúčame blog M. Fatih Tüzen: Handling Missing Data in R: A Comprehensive Guide, R bloggers.

E3te raz si pozrime našu pôvodnú databázu s chýbajúcimi údajmi:

Databáza s chýbajúcimi údajmi
Databáza s chýbajúcimi údajmi
library(mice)
library(VIM)
## Loading required package: colorspace
## Loading required package: grid
## Registered S3 method overwritten by 'car':
##   method           from
##   na.action.merMod lme4
## VIM is ready to use.
## Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues
## 
## Attaching package: 'VIM'
## The following object is masked from 'package:datasets':
## 
##     sleep
# Count missing values in each column
print("pocet chybajucich udajov za jednotlive premenne")
## [1] "pocet chybajucich udajov za jednotlive premenne"
colSums(is.na(udaje1))
## YEAR COMP EXCH PRIM TOBI MARK RETU DEBT FIRM SOCI ENVI GOVE ESG. 
##    1    9    9   10    9   11    9   17   11   10   10   11   11

Štatistika vyššie nám hovorí, koľko NA má ktorý stĺpec databázy. Ďalšie riadky nám hovoria o štruktúre záznamov, kde sa nachádzajú chýbajúce hodnoty. Posledný riadok hovorí o počte chýbajúcich údajov za jednotlivé premenné a za celú databázu. Máme 760 záznamov , z kotých 754 je úplných a mámo 8 chýbajúcich hodnôt. Podbnú informáciu nám dáva nasledovný graf.

# pattern of missingness
md.pattern(udaje1)

##     YEAR COMP EXCH TOBI RETU PRIM SOCI ENVI MARK FIRM GOVE ESG. DEBT    
## 744    1    1    1    1    1    1    1    1    1    1    1    1    1   0
## 6      1    1    1    1    1    1    1    1    1    1    1    1    0   1
## 1      1    1    1    1    1    1    1    1    1    1    1    0    1   1
## 1      1    1    1    1    1    1    1    1    1    1    1    0    0   2
## 1      1    1    1    1    1    1    1    1    1    1    0    1    1   1
## 1      1    1    1    1    1    1    1    1    1    0    1    1    1   1
## 2      1    1    1    1    1    1    1    1    0    1    1    1    1   1
## 1      1    1    1    1    1    1    1    0    1    1    1    1    1   1
## 1      1    1    1    1    1    1    0    1    1    1    0    1    0   3
## 1      1    1    1    1    1    0    1    1    1    0    1    1    1   2
## 9      1    0    0    0    0    0    0    0    0    0    0    0    0  12
## 1      0    1    1    1    1    1    1    1    1    1    1    1    1   1
##        1    9    9    9    9   10   10   10   11   11   11   11   17 128
# visualize missing data
aggr(udaje1, bars=FALSE,col=c('navyblue','red'), numbers=TRUE, sortVars=TRUE)  # cervena farba signalizuje chybahuce polozky

## 
##  Variables sorted by number of missings: 
##  Variable      Count
##      DEBT 0.02210663
##      MARK 0.01430429
##      FIRM 0.01430429
##      GOVE 0.01430429
##      ESG. 0.01430429
##      PRIM 0.01300390
##      SOCI 0.01300390
##      ENVI 0.01300390
##      COMP 0.01170351
##      EXCH 0.01170351
##      TOBI 0.01170351
##      RETU 0.01170351
##      YEAR 0.00130039
# multiple imputation - v pripade, ak vam chyba mensi rozsah udajov
imp <- mice(udaje1, seed=123)   # konkretne parametre imputacie vieme nastavovat - pozri help
## 
##  iter imp variable
##   1   1  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   1   2  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   1   3  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   1   4  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   1   5  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   2   1  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   2   2  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   2   3  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   2   4  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   2   5  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   3   1  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   3   2  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   3   3  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   3   4  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   3   5  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   4   1  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   4   2  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   4   3  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   4   4  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   4   5  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   5   1  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   5   2  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   5   3  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   5   4  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
##   5   5  YEAR  TOBI  MARK  RETU  DEBT  FIRM  SOCI  ENVI  GOVE  ESG.
## Warning: Number of logged events: 3
udaje_imputovane <- complete(imp, 1)
udaje1 <- udaje_imputovane
head(udaje1)
rm(imp)
rm(udaje_imputovane)
print("pocet chybajucich udajov za jednotlive premenne")
## [1] "pocet chybajucich udajov za jednotlive premenne"
colSums(is.na(udaje1))
## YEAR COMP EXCH PRIM TOBI MARK RETU DEBT FIRM SOCI ENVI GOVE ESG. 
##    0    9    9   10    0    0    0    0    0    0    0    0    0

Celkove nám teda ostala nevyplnená jedna premenná - textová - ktorá označuje Primary Business referencovanej firmy

Tabuľky, grafy, jednoduché štatistiky

Grafy

ggplot2 - knižnica pre grafy

Výber a následné triedenie

library(dplyr)

udaje.2019 <- udaje1 %>%
  filter(YEAR == 2019) %>%
  dplyr::select(RETU, ESG., DEBT, FIRM)

Knižnica .ggplot2. je v súčasnosti najčastejšie používaná grafická knižnica, pričom predpripravené kódy k jednotlivým obrázkom si viete nájsť v R Graph Gallery. Tu si uvedieme jednoduchšie z nich.

Scatter plot

# Basic scatter plot
library(ggplot2)
ggplot(udaje.2019, aes(x = DEBT, y = ESG.)) +            # specifikacia osi
  geom_point() +                                                   # typ grafu 
  theme_minimal() +
  labs(title = "ESG index vs Debt", x = "Debt to Asset", y = "ESG Score")      # oznacenie osi

Boxplot

# Bar plot with grouping
library(ggplot2)

library(ggplot2)

ggplot(udaje1, aes(x = factor(YEAR), y = DEBT)) +        # specifikacia osi
  geom_boxplot(fill = "lightgreen", color = "blue") +      # typ grafu - boxplot
  labs(                                                       # oznacenie nazov grafu
    title = "Debt to Asset by Year",
    x = "Year",
    y = "Debt to Asset"
  ) +
  theme_minimal()

Uloha 5

Základné štatistiky Pre Logisitcs

model <- lm(
  waiting_time ~ traffic_status + asset_utilization +
    demand_forecast + temperature + humidity +
    user_transaction_amount,
  data = log_data
)

summary(model)
## 
## Call:
## lm(formula = waiting_time ~ traffic_status + asset_utilization + 
##     demand_forecast + temperature + humidity + user_transaction_amount, 
##     data = log_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -25.9640 -12.3080  -0.1745  13.1881  26.5799 
## 
## Coefficients:
##                          Estimate Std. Error t value Pr(>|t|)    
## (Intercept)             30.843357   6.151365   5.014 6.31e-07 ***
## traffic_statusDetour    -0.285720   1.118747  -0.255    0.798    
## traffic_statusHeavy     -1.339343   1.135331  -1.180    0.238    
## asset_utilization        0.022183   0.039666   0.559    0.576    
## demand_forecast         -0.007174   0.007684  -0.934    0.351    
## temperature              0.073440   0.138299   0.531    0.596    
## humidity                 0.050967   0.052518   0.970    0.332    
## user_transaction_amount -0.002176   0.003900  -0.558    0.577    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 14.5 on 992 degrees of freedom
## Multiple R-squared:  0.00415,    Adjusted R-squared:  -0.002877 
## F-statistic: 0.5905 on 7 and 992 DF,  p-value: 0.764

knitr - tabuľka

library(dplyr)
library(knitr)

traffic_waiting_stats <- log_data %>%
  group_by(traffic_status) %>%
  summarise(
    n      = n(),
    mean   = mean(waiting_time, na.rm = TRUE),
    sd     = sd(waiting_time, na.rm = TRUE),
    min    = min(waiting_time, na.rm = TRUE),
    q25    = quantile(waiting_time, 0.25, na.rm = TRUE),
    median = median(waiting_time, na.rm = TRUE),
    q75    = quantile(waiting_time, 0.75, na.rm = TRUE),
    max    = max(waiting_time, na.rm = TRUE),
    .groups = "drop"
  )

kable(traffic_waiting_stats, digits = 2, caption = "Descriptive statistics of Waiting Time by Traffic Status")
Descriptive statistics of Waiting Time by Traffic Status
traffic_status n mean sd min q25 median q75 max
Clear 328 35.54 14.94 10 22 35 49 60
Detour 345 35.31 13.84 10 24 35 47 60
Heavy 327 34.32 14.68 10 22 34 49 60

alebo krajšie tabuľky s pomocou .kableExtra.:

library(dplyr)
library(knitr)
library(kableExtra)
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
waiting_stats <- log_data %>%
  summarise(
    n      = n(),
    mean   = mean(waiting_time, na.rm = TRUE),
    sd     = sd(waiting_time, na.rm = TRUE),
    min    = min(waiting_time, na.rm = TRUE),
    q25    = quantile(waiting_time, 0.25, na.rm = TRUE),
    median = median(waiting_time, na.rm = TRUE),
    q75    = quantile(waiting_time, 0.75, na.rm = TRUE),
    max    = max(waiting_time, na.rm = TRUE)
  )

waiting_stats %>%
  kable(digits = 2, caption = "Basic statistics of Waiting Time") %>%
  kable_styling(full_width = FALSE, bootstrap_options = c("striped", "condensed", "hover")) %>%
  add_header_above(c("Waiting Time statistics" = 8))
Basic statistics of Waiting Time
Waiting Time statistics
n mean sd min q25 median q75 max
1000 35.06 14.48 10 23 35 49 60

Main Anylize Logisitcs

library(dplyr)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
log_data <- read.csv(
  "smart_logistics_dataset.csv",
  header = TRUE,
  sep = ",",
  dec = ".",
  stringsAsFactors = FALSE
)

# Очистка назв
log_data <- log_data %>% clean_names()


names(log_data) <- tolower(names(log_data))
names(log_data) <- gsub(" ", "_", names(log_data))

head(log_data)
str(log_data)
## 'data.frame':    1000 obs. of  16 variables:
##  $ timestamp              : chr  "2024-03-20 00:11:14" "2024-10-30 07:53:51" "2024-07-29 18:42:48" "2024-10-28 00:50:54" ...
##  $ asset_id               : chr  "Truck_7" "Truck_6" "Truck_10" "Truck_9" ...
##  $ latitude               : num  -65.7 22.3 54.9 42.4 -65.8 ...
##  $ longitude              : num  11.25 -131.71 79.55 -1.48 47.95 ...
##  $ inventory_level        : int  390 491 190 330 480 118 480 222 245 389 ...
##  $ shipment_status        : chr  "Delayed" "In Transit" "In Transit" "Delivered" ...
##  $ temperature            : num  27 22.5 25.2 25.4 20.5 24.3 20.7 23.3 26.4 21.9 ...
##  $ humidity               : num  67.8 54.3 62.2 52.3 57.2 61.8 75.4 64.2 77.2 57.3 ...
##  $ traffic_status         : chr  "Detour" "Heavy" "Detour" "Heavy" ...
##  $ waiting_time           : int  38 16 34 37 56 56 32 30 14 52 ...
##  $ user_transaction_amount: int  320 439 355 227 197 258 263 459 183 127 ...
##  $ user_purchase_frequency: int  4 7 3 5 6 10 3 9 2 7 ...
##  $ logistics_delay_reason : chr  "None" "Weather" "None" "Traffic" ...
##  $ asset_utilization      : num  60.1 80.9 99.2 97.4 71.6 66.8 73.3 73.8 69.6 63.1 ...
##  $ demand_forecast        : int  285 174 260 160 270 189 198 253 206 224 ...
##  $ logistics_delay        : int  1 1 0 1 1 0 1 0 0 0 ...

Testovanie hypotéz

# Testovanie hypotéz

#### t-test: Porovnanie waiting_time pre Clear a Heavy

t_test_result <- t.test(
  log_data$waiting_time[log_data$traffic_status == "Clear"],
  log_data$waiting_time[log_data$traffic_status == "Heavy"]
)

print(t_test_result)
## 
##  Welch Two Sample t-test
## 
## data:  log_data$waiting_time[log_data$traffic_status == "Clear"] and log_data$waiting_time[log_data$traffic_status == "Heavy"]
## t = 1.0554, df = 652.86, p-value = 0.2916
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -1.051269  3.494433
## sample estimates:
## mean of x mean of y 
##  35.54268  34.32110

ANOVA: Comparing Reading Scores Across Programs

anova_result <- aov(waiting_time ~ traffic_status, data = log_data)
summary(anova_result)
##                 Df Sum Sq Mean Sq F value Pr(>F)
## traffic_status   2    276   138.0   0.658  0.518
## Residuals      997 209120   209.8

Linear Regression: Predicting Math Scores

library(dplyr)
names(log_data)
##  [1] "timestamp"               "asset_id"               
##  [3] "latitude"                "longitude"              
##  [5] "inventory_level"         "shipment_status"        
##  [7] "temperature"             "humidity"               
##  [9] "traffic_status"          "waiting_time"           
## [11] "user_transaction_amount" "user_purchase_frequency"
## [13] "logistics_delay_reason"  "asset_utilization"      
## [15] "demand_forecast"         "logistics_delay"
str(log_data)
## 'data.frame':    1000 obs. of  16 variables:
##  $ timestamp              : chr  "2024-03-20 00:11:14" "2024-10-30 07:53:51" "2024-07-29 18:42:48" "2024-10-28 00:50:54" ...
##  $ asset_id               : chr  "Truck_7" "Truck_6" "Truck_10" "Truck_9" ...
##  $ latitude               : num  -65.7 22.3 54.9 42.4 -65.8 ...
##  $ longitude              : num  11.25 -131.71 79.55 -1.48 47.95 ...
##  $ inventory_level        : int  390 491 190 330 480 118 480 222 245 389 ...
##  $ shipment_status        : chr  "Delayed" "In Transit" "In Transit" "Delivered" ...
##  $ temperature            : num  27 22.5 25.2 25.4 20.5 24.3 20.7 23.3 26.4 21.9 ...
##  $ humidity               : num  67.8 54.3 62.2 52.3 57.2 61.8 75.4 64.2 77.2 57.3 ...
##  $ traffic_status         : chr  "Detour" "Heavy" "Detour" "Heavy" ...
##  $ waiting_time           : int  38 16 34 37 56 56 32 30 14 52 ...
##  $ user_transaction_amount: int  320 439 355 227 197 258 263 459 183 127 ...
##  $ user_purchase_frequency: int  4 7 3 5 6 10 3 9 2 7 ...
##  $ logistics_delay_reason : chr  "None" "Weather" "None" "Traffic" ...
##  $ asset_utilization      : num  60.1 80.9 99.2 97.4 71.6 66.8 73.3 73.8 69.6 63.1 ...
##  $ demand_forecast        : int  285 174 260 160 270 189 198 253 206 224 ...
##  $ logistics_delay        : int  1 1 0 1 1 0 1 0 0 0 ...
log_data$logistics_delay <- as.factor(log_data$logistics_delay)

model_logit <- glm(
  logistics_delay ~ waiting_time +
    traffic_status +
    asset_utilization +
    demand_forecast +
    temperature +
    humidity +
    user_transaction_amount,
  data = log_data,
  family = binomial
)

summary(model_logit)
## 
## Call:
## glm(formula = logistics_delay ~ waiting_time + traffic_status + 
##     asset_utilization + demand_forecast + temperature + humidity + 
##     user_transaction_amount, family = binomial, data = log_data)
## 
## Coefficients:
##                           Estimate Std. Error z value Pr(>|z|)
## (Intercept)              1.470e+00  1.108e+00   1.327    0.185
## waiting_time            -8.594e-03  5.661e-03  -1.518    0.129
## traffic_statusDetour     4.734e-02  1.622e-01   0.292    0.770
## traffic_statusHeavy      2.021e+01  5.917e+02   0.034    0.973
## asset_utilization       -5.931e-03  7.003e-03  -0.847    0.397
## demand_forecast         -1.515e-05  1.365e-03  -0.011    0.991
## temperature             -3.445e-02  2.455e-02  -1.404    0.160
## humidity                -1.027e-02  9.426e-03  -1.090    0.276
## user_transaction_amount  5.642e-04  6.836e-04   0.825    0.409
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1368.82  on 999  degrees of freedom
## Residual deviance:  868.49  on 991  degrees of freedom
## AIC: 886.49
## 
## Number of Fisher Scoring iterations: 18

Main Program

log_data <- read.csv("smart_logistics_dataset.csv", header = TRUE, stringsAsFactors = FALSE)

names(log_data) <- tolower(names(log_data))
names(log_data) <- gsub(" ", "_", names(log_data))

log_data$traffic_status <- as.factor(log_data$traffic_status)
log_data$shipment_status <- as.factor(log_data$shipment_status)
log_data$logistics_delay_reason <- as.factor(log_data$logistics_delay_reason)
log_data$asset_id <- as.factor(log_data$asset_id)
log_data$logistics_delay <- as.factor(log_data$logistics_delay)

Uloha 6

setwd("D:/reposit/11955973")

library(lmtest)
library(car)
library(tseries)
library(dplyr)

Import údajov

log_data <- read.csv(
  "smart_logistics_dataset.csv",
  header = TRUE,
  sep = ",",
  dec = ".",
  stringsAsFactors = FALSE
)

names(log_data) <- tolower(names(log_data))
names(log_data) <- gsub(" ", "_", names(log_data))

log_data$traffic_status <- as.factor(log_data$traffic_status)
log_data$shipment_status <- as.factor(log_data$shipment_status)
log_data$logistics_delay_reason <- as.factor(log_data$logistics_delay_reason)
log_data$asset_id <- as.factor(log_data$asset_id)

Odhad modelu

model <- lm(
  waiting_time ~ traffic_status + asset_utilization +
    demand_forecast + temperature + humidity +
    user_transaction_amount,
  data = log_data
)

summary(model)
## 
## Call:
## lm(formula = waiting_time ~ traffic_status + asset_utilization + 
##     demand_forecast + temperature + humidity + user_transaction_amount, 
##     data = log_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -25.9640 -12.3080  -0.1745  13.1881  26.5799 
## 
## Coefficients:
##                          Estimate Std. Error t value Pr(>|t|)    
## (Intercept)             30.843357   6.151365   5.014 6.31e-07 ***
## traffic_statusDetour    -0.285720   1.118747  -0.255    0.798    
## traffic_statusHeavy     -1.339343   1.135331  -1.180    0.238    
## asset_utilization        0.022183   0.039666   0.559    0.576    
## demand_forecast         -0.007174   0.007684  -0.934    0.351    
## temperature              0.073440   0.138299   0.531    0.596    
## humidity                 0.050967   0.052518   0.970    0.332    
## user_transaction_amount -0.002176   0.003900  -0.558    0.577    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 14.5 on 992 degrees of freedom
## Multiple R-squared:  0.00415,    Adjusted R-squared:  -0.002877 
## F-statistic: 0.5905 on 7 and 992 DF,  p-value: 0.764

\[ WaitingTime_i = \beta_0 + \beta_1 TrafficStatus_i + \beta_2 AssetUtilization_i + \beta_3 DemandForecast_i + \beta_4 Temperature_i + \beta_5 Humidity_i + \beta_6 UserTransactionAmount_i + \varepsilon_i \]

Predpokladáme, že horšia dopravná situácia, vyššie využitie aktív a vyšší dopyt budú zvyšovať waiting time. Vplyv teploty, vlhkosti a objemu transakcií môže byť doplnkový a závisí od konkrétnych podmienok logistického systému.


# Diagnostické grafy

## Residuals vs Fitted


``` r
plot(model, which = 1)
Residuals vs Fitted

Residuals vs Fitted

Q-Q plot

plot(model, which = 2)
Normal Q-Q plot

Normal Q-Q plot

Scale-Location plot

plot(model, which = 3)
Scale-Location plot

Scale-Location plot

Residuals vs Leverage

plot(model, which = 5)
Residuals vs Leverage

Residuals vs Leverage

Test normality rezíduí

Shapiro-Wilkov test

shapiro.test(residuals(model))
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(model)
## W = 0.95642, p-value < 2.2e-16

Jarque-Bera test

jarque.bera.test(residuals(model))
## 
##  Jarque Bera Test
## 
## data:  residuals(model)
## X-squared = 59.808, df = 2, p-value = 1.03e-13

Test heteroskedasticity

Breusch-Pagan test

bptest(model)
## 
##  studentized Breusch-Pagan test
## 
## data:  model
## BP = 13.03, df = 7, p-value = 0.07137

Whiteov test

bptest(model, ~ fitted(model) + I(fitted(model)^2))
## 
##  studentized Breusch-Pagan test
## 
## data:  model
## BP = 2.1993, df = 2, p-value = 0.333

Test autokorelácie

Durbin-Watson test

dwtest(model)
## 
##  Durbin-Watson test
## 
## data:  model
## DW = 2.0246, p-value = 0.6518
## alternative hypothesis: true autocorrelation is greater than 0

Breusch-Godfrey test

bgtest(model, order = 1)
## 
##  Breusch-Godfrey test for serial correlation of order up to 1
## 
## data:  model
## LM test = 0.17434, df = 1, p-value = 0.6763

Odľahlé a vplyvné pozorovania

Test na odľahlé hodnoty

outlierTest(model)
## No Studentized residuals with Bonferroni p < 0.05
## Largest |rstudent|:
##     rstudent unadjusted p-value Bonferroni p
## 747 1.843817           0.065508           NA

Cookova vzdialenosť

cd <- cooks.distance(model)
head(sort(cd, decreasing = TRUE), 10)
##         396         911         339         387         275         318 
## 0.005246235 0.004958983 0.004553595 0.004365973 0.004184096 0.004112915 
##         713         775         568          41 
## 0.004110580 0.004046313 0.004030576 0.003877755

Na základe vykonanej analýzy logistického datasetu boli použité viaceré štatistické metódy vrátane deskriptívnej štatistiky, lineárnej regresie, logistickej regresie a diagnostických testov.

Deskriptívna analýza ukázala, že priemerné hodnoty waiting_time sa medzi jednotlivými kategóriami traffic_status výrazne nelíšia. Tento výsledok bol potvrdený aj pomocou t-testu a ANOVA, kde nebol zistený štatisticky významný rozdiel medzi skupinami.

Lineárny regresný model nevykázal štatisticky významné koeficienty, čo znamená, že zvolené vysvetľujúce premenné nemajú významný vplyv na waiting_time. Diagnostické testy ukázali porušenie predpokladu normality rezíduí, avšak neboli identifikované vážne problémy s heteroskedasticitou alebo autokoreláciou.

Logistický regresný model, ktorý skúmal pravdepodobnosť logistického oneskorenia, taktiež neidentifikoval štatisticky významné premenné. To naznačuje, že oneskorenia sú pravdepodobne ovplyvnené inými faktormi, ktoré nie sú zahrnuté v modeli.

Celkovo možno konštatovať, že analyzovaný dataset neposkytuje dostatočne silné dôkazy o vplyve vybraných premenných na waiting_time ani na pravdepodobnosť logistického oneskorenia.