# ==== 0) Pustaka ====
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.3
## Warning: package 'ggplot2' was built under R version 4.2.3
## Warning: package 'tidyr' was built under R version 4.2.3
## Warning: package 'purrr' was built under R version 4.2.3
## Warning: package 'dplyr' was built under R version 4.2.3
## Warning: package 'stringr' was built under R version 4.2.3
## Warning: package 'lubridate' was built under R version 4.2.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.0
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(survival)
library(broom)
## Warning: package 'broom' was built under R version 4.2.3
library(lubridate)

setwd("D:/KULIAH/Semester 7/Data Hauler")
df <- read.csv("dengan dummy.csv", sep=";", dec=",", stringsAsFactors = FALSE, na.strings = c("","NA"))

# ==== 1) Bersihkan nama kolom & konversi tipe ====
df <- df %>% janitor::clean_names()

num_cols <- c("d1","d2","d3","d4","d5","p1","p2","p3",
              "start_time","stop_time","gap","status",
              "hm_break_down","event_order")

df <- df %>% 
  mutate(across(all_of(num_cols), ~ suppressWarnings(as.numeric(.))))

# ==== Pastikan urutan event valid ====
df <- df %>%
  filter(!is.na(stop_time), !is.na(start_time), !is.na(gap),
         stop_time >= start_time, gap >= 0) %>%
  group_by(equipment = if ("equipment" %in% names(.)) equipment else "UNIT") %>%
  arrange(start_time, stop_time, .by_group = TRUE) %>%
  mutate(event_order = if_else(is.na(event_order), row_number(), event_order)) %>%
  ungroup()

# ==== 2) MAPPING D1..D5 & P1..P3 ====
comp_map_detect <- df %>%
  filter(toupper(object_name) != "ENGINE") %>%
  rowwise() %>%
  mutate(which_d = c("d1","d2","d3","d4","d5")[which.max(c_across(d1:d5))]) %>%
  ungroup() %>%
  count(object_name, which_d, sort = TRUE) %>%
  group_by(object_name) %>%
  slice_max(n, n = 1, with_ties = FALSE) %>%
  ungroup()

comp_map <- setNames(comp_map_detect$object_name, comp_map_detect$which_d)
comp_baseline <- "ENGINE"

plant_map_detect <- df %>%
  filter(toupper(maintenance_plant) != "ADT") %>%
  rowwise() %>%
  mutate(which_p = c("p1","p2","p3")[which.max(c_across(p1:p3))]) %>%
  ungroup() %>%
  count(maintenance_plant, which_p, sort = TRUE) %>%
  group_by(maintenance_plant) %>%
  slice_max(n, n = 1, with_ties = FALSE) %>%
  ungroup()

plant_map <- setNames(plant_map_detect$maintenance_plant, plant_map_detect$which_p)
plant_baseline <- "ADT"

message("Mapping komponen terdeteksi:")
## Mapping komponen terdeteksi:
print(comp_map)
##                d1                d2                d3                d4 
##    "DIFFERENTIAL"     "FINAL DRIVE" "FRAME & CHASSIS"      "SUSPENSION" 
##                d5 
##    "TRANSMISSION"
message("Mapping plant terdeteksi:")
## Mapping plant terdeteksi:
print(plant_map)
##    p1    p2    p3 
## "BIN" "IPR" "SDJ"
# ==== 3) VALIDASI BASELINE ====
engine_ok <- df %>% filter(toupper(object_name)==comp_baseline) %>%
  summarise(ok = all(d1==0 & d2==0 & d3==0 & d4==0 & d5==0)) %>% pull(ok)

adt_ok <- df %>% filter(toupper(maintenance_plant)==plant_baseline) %>%
  summarise(ok = all(p1==0 & p2==0 & p3==0)) %>% pull(ok)

message("Baseline ENGINE all-zero? ", engine_ok)
## Baseline ENGINE all-zero? TRUE
message("Baseline ADT all-zero? ", adt_ok)
## Baseline ADT all-zero? TRUE
# ==== 4) PARETO ====
pareto_df <- df %>%
  filter(status == 1) %>%
  count(object_name, name = "freq") %>%
  arrange(desc(freq)) %>%
  mutate(prop = freq/sum(freq),
         cum_prop = cumsum(prop),
         object_name = forcats::fct_reorder(object_name, freq))

gg_pareto <- ggplot(pareto_df, aes(x = object_name, y = freq)) +
  geom_col(width = 0.7) +
  geom_point(aes(y = cum_prop * max(freq)), size = 2) +
  geom_line(aes(y = cum_prop * max(freq), group = 1)) +
  geom_hline(yintercept = 0.8 * max(pareto_df$freq), linetype = "dashed") +
  scale_y_continuous(name = "Frekuensi Kerusakan",
                     sec.axis = sec_axis(~ . / max(pareto_df$freq),
                                         labels = scales::percent, name = "Kumulatif")) +
  labs(x = "Komponen (Object Name)",
       title = "Pareto Kerusakan per Komponen") +
  theme_minimal(base_size = 12) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(gg_pareto)

# ==== 4B) ANALISIS DESKRIPTIF DATA KERUSAKAN ====

# 1️⃣ Frekuensi kerusakan per unit dan per komponen
freq_unit <- df %>%
  filter(status == 1) %>%
  count(equipment, name = "freq") %>%
  arrange(desc(freq))

freq_comp <- df %>%
  filter(status == 1) %>%
  count(object_name, name = "freq") %>%
  arrange(desc(freq))

message("Top 10 Unit dengan frekuensi kerusakan tertinggi:")
## Top 10 Unit dengan frekuensi kerusakan tertinggi:
print(head(freq_unit, 10))
## # A tibble: 10 × 2
##    equipment  freq
##    <chr>     <int>
##  1 HDKM78085    51
##  2 HDKM78193    51
##  3 HDKM78196    51
##  4 HDKM78205    51
##  5 HDKM78213    51
##  6 HDKM78215    51
##  7 HDKM78216    51
##  8 HDKM78220    51
##  9 HDKM78222    51
## 10 HDKM78229    51
message("Frekuensi kerusakan per komponen:")
## Frekuensi kerusakan per komponen:
print(freq_comp)
## # A tibble: 6 × 2
##   object_name      freq
##   <chr>           <int>
## 1 ENGINE           3259
## 2 SUSPENSION       1307
## 3 FRAME & CHASSIS  1284
## 4 TRANSMISSION      489
## 5 FINAL DRIVE        62
## 6 DIFFERENTIAL       39
freq_comp <- df %>%
  filter(status == 1) %>%
  count(object_name, name = "freq") %>%
  arrange(desc(freq)) %>%
  mutate(persentase = round(freq / sum(freq) * 100,2))


gg_freq_comp <- ggplot(freq_comp,
                       aes(x = fct_reorder(object_name, freq), y = freq)) +
  geom_col(fill = "steelblue", width = 0.7) +
  geom_text(
    aes(label = paste0(freq, "\n", round(persentase, 1), "%")),
    hjust = -0.15,
    size = 4,
    fontface = "bold",
    lineheight = 0.9
  ) +
  coord_flip() +
  scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
  labs(
    x = "Komponen",
    y = "Frekuensi Kerusakan",
    title = "Frekuensi dan Persentase Kerusakan per Komponen"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    axis.title = element_text(face = "bold", size = 14),  
    axis.text  = element_text(size = 12),
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5)
  )

print(gg_freq_comp)

freq_site <- df %>%
  filter(status == 1) %>%
  count(maintenance_plant, name = "freq") %>%
  arrange(desc(freq)) %>%
  mutate(persentase = round(freq / sum(freq) * 100,2))


gg_freq_site <- ggplot(freq_site,
                       aes(x = fct_reorder(maintenance_plant, freq), y = freq)) +
  geom_col(fill = "darkgreen", width = 0.7) +
  geom_text(
    aes(label = paste0(freq, "\n", persentase, "%")),
    hjust = -0.15,
    size = 4,
    fontface = "bold",
    lineheight = 0.9
  ) +
  coord_flip() +
  scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
  labs(
    x = "Site",
    y = "Frekuensi Kerusakan",
    title = "Frekuensi dan Persentase Kerusakan per Site"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    axis.title = element_text(face = "bold", size = 14),  # <<< INI
    axis.text  = element_text(size = 12),
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5)
  )

print(gg_freq_site)

# 2️⃣ Analisis gap time antar kerusakan
# Jika belum ada kolom gap_gt, hitung kembali untuk eksplorasi
df_gap <- df %>%
  group_by(equipment) %>%
  arrange(stop_time, .by_group = TRUE) %>%
  mutate(
    prev_stop = lag(stop_time),
    gap_time = if_else(!is.na(prev_stop),
                       stop_time - prev_stop,
                       pmax(stop_time - start_time, 0))
  ) %>%
  ungroup() %>%
  filter(!is.na(gap_time), gap_time > 0)

# Statistik deskriptif gap time
gap_summary <- df_gap %>%
  summarise(
    n = n(),
    mean_gap = mean(gap_time, na.rm = TRUE),
    median_gap = median(gap_time, na.rm = TRUE),
    var_gap = var(gap_time, na.rm = TRUE),
    sd_gap = sd(gap_time, na.rm = TRUE),
    min_gap = min(gap_time, na.rm = TRUE),
    max_gap = max(gap_time, na.rm = TRUE)
  )
message("Ringkasan statistik gap time:")
## Ringkasan statistik gap time:
print(gap_summary)
## # A tibble: 1 × 7
##       n mean_gap median_gap var_gap sd_gap min_gap max_gap
##   <int>    <dbl>      <dbl>   <dbl>  <dbl>   <dbl>   <dbl>
## 1  6433     123.       58.5  37011.   192.  0.0100    3352
# 3️⃣ Visualisasi distribusi gap time
gg_gap_hist <- ggplot(df_gap, aes(x = gap_time)) +
  geom_histogram(binwidth = diff(range(df_gap$gap_time, na.rm = TRUE))/30,
                 fill = "orange", color = "black", alpha = 0.7) +
  labs(x = "Gap Time (jam atau HM)", y = "Frekuensi",
       title = "Distribusi Interval Waktu Antar Kerusakan (Gap Time)") +
  theme_minimal(base_size = 12)
print(gg_gap_hist)

# ==== 5) UJI LAPLACE ====
laplace_test <- function(times_vec){
  times_vec <- sort(times_vec)
  n <- length(times_vec)
  if(n < 2) return(tibble(Z = NA_real_, p_value = NA_real_, n = n, T = NA_real_))
  Ttot <- max(times_vec)
  S <- sum((1:n) * times_vec)
  Z <- (S/n - 0.5*Ttot) / sqrt(Ttot^3/(12*n))
  tibble(Z = Z, p_value = 2*(1 - pnorm(abs(Z))), n = n, T = Ttot)
}

laplace_overall <- laplace_test(df %>% filter(status == 1) %>% pull(stop_time))
print(laplace_overall)
## # A tibble: 1 × 4
##       Z p_value     n     T
##   <dbl>   <dbl> <int> <dbl>
## 1 3444.       0  6440 23957
# === 7) PWP–GT (baseline) ===
# Hitung ulang gap_gt sesuai definisi PWP-GT
df_gt <- df %>%
  group_by(equipment) %>%
  arrange(stop_time, .by_group = TRUE) %>%
  mutate(
    prev_stop = lag(stop_time),
    gap_gt = if_else(
      !is.na(prev_stop),
      stop_time - prev_stop,              # gap antar kerusakan
      pmax(stop_time - start_time, 0)     # event pertama
    ),
    gap_gt = pmax(gap_gt, 0)              # tidak boleh negatif
  ) %>%
  ungroup() %>%
  select(-prev_stop) %>%
  mutate(
    start_gt = 0,
    stop_gt = gap_gt
  )

# Hanya ambil event dengan durasi valid
df_gt <- df_gt %>% filter(stop_gt > 0 | status == 0)

# === Model PWP–GT ===
form_gt <- as.formula(
  Surv(start_gt, stop_gt, status) ~
    d1 + d2 + d3 + d4 + d5 +
    p1 + p2 + p3 +
    strata(event_order) +
    cluster(equipment)
)

fit_pwp_gt <- coxph(form_gt, data = df_gt, ties = "efron")
summary(fit_pwp_gt)
## Call:
## coxph(formula = Surv(start_gt, stop_gt, status) ~ d1 + d2 + d3 + 
##     d4 + d5 + p1 + p2 + p3 + strata(event_order), data = df_gt, 
##     ties = "efron", cluster = equipment)
## 
##   n= 6433, number of events= 6433 
## 
##        coef exp(coef) se(coef) robust se      z Pr(>|z|)    
## d1 -0.37603   0.68658  0.16691   0.16437 -2.288   0.0222 *  
## d2 -0.00532   0.99469  0.13341   0.21462 -0.025   0.9802    
## d3 -0.22467   0.79878  0.03372   0.03696 -6.078 1.22e-09 ***
## d4 -0.16488   0.84800  0.03378   0.04006 -4.116 3.85e-05 ***
## d5 -0.08907   0.91478  0.04988   0.06181 -1.441   0.1496    
## p1 -0.02952   0.97092  0.04531   0.04416 -0.668   0.5039    
## p2 -0.05548   0.94603  0.02759   0.04464 -1.243   0.2139    
## p3  0.08693   1.09082  0.07214   0.05829  1.491   0.1359    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
##    exp(coef) exp(-coef) lower .95 upper .95
## d1    0.6866     1.4565    0.4975    0.9476
## d2    0.9947     1.0053    0.6531    1.5149
## d3    0.7988     1.2519    0.7430    0.8588
## d4    0.8480     1.1792    0.7840    0.9173
## d5    0.9148     1.0932    0.8104    1.0326
## p1    0.9709     1.0300    0.8904    1.0587
## p2    0.9460     1.0570    0.8668    1.0325
## p3    1.0908     0.9167    0.9731    1.2228
## 
## Concordance= 0.533  (se = 0.005 )
## Likelihood ratio test= 66.47  on 8 df,   p=2e-11
## Wald test            = 51.42  on 8 df,   p=2e-08
## Score (logrank) test = 65.96  on 8 df,   p=3e-11,   Robust = 37.54  p=9e-06
## 
##   (Note: the likelihood ratio and score tests assume independence of
##      observations within a cluster, the Wald and robust score tests do not).
# Uji asumsi PH
ph_gt <- cox.zph(fit_pwp_gt, transform = "km")
print(ph_gt)
##          chisq df      p
## d1      0.3435  1 0.5578
## d2      4.9519  1 0.0261
## d3     10.5054  1 0.0012
## d4      0.3337  1 0.5635
## d5      1.6923  1 0.1933
## p1      0.0298  1 0.8629
## p2      4.0338  1 0.0446
## p3      0.6319  1 0.4266
## GLOBAL 22.0286  8 0.0049
# ===============================================================
# 8) PWP–GT + TVC BERDASARKAN QUARTER KALENDER (Q3_2024 → Q2_2025)
# ===============================================================

df <- df %>%
  mutate(
    breakdown_date = suppressWarnings(parse_date_time(
      breakdown_date,
      orders = c("d/m/Y","d-m-Y","Y-m-d","m/d/Y","m-d-Y")
    )),
    month = lubridate::month(breakdown_date),
    year  = lubridate::year(breakdown_date),
    
    # Mapping quarter aktual:
    cal_interval4 = case_when(
      year == 2024 & month %in% 7:9   ~ "Q3_2024",   # baseline
      year == 2024 & month %in% 10:12 ~ "Q4_2024",
      year == 2025 & month %in% 1:3   ~ "Q1_2025",
      year == 2025 & month %in% 4:6   ~ "Q2_2025",
      TRUE ~ NA_character_
    ),
    
    cal_interval4 = factor(cal_interval4,
                           levels = c("Q3_2024","Q4_2024","Q1_2025","Q2_2025"))
  )

# ==== Setup ulang untuk PWP–GT + TVC ====
df_tv <- df %>%
  filter(!is.na(cal_interval4)) %>%
  group_by(equipment) %>%
  arrange(start_time, stop_time, .by_group = TRUE) %>%
  mutate(event_order = row_number()) %>%
  ungroup()

df_tv <- df_tv %>%
  group_by(equipment) %>%
  arrange(stop_time, .by_group = TRUE) %>%
  mutate(
    prev_stop = lag(stop_time),
    gap_gt = if_else(
      !is.na(prev_stop),
      stop_time - prev_stop,              # gap antar kejadian
      pmax(stop_time - start_time, 0)     # event pertama
    ),
    gap_gt = pmax(gap_gt, 0)
  ) %>%
  ungroup() %>%
  select(-prev_stop)

df_tv <- df_tv %>%
  mutate(
    start_gt = 0,
    stop_gt = gap_gt
  ) %>%
  filter(stop_gt > 0 | status == 0)

# ==== FINAL MODEL PWP–GT + TVC (Quarter) ====
form_gt_tv <- as.formula(
  Surv(start_gt, stop_gt, status) ~
    (d1 + d2 + d3 + d4 + d5 + p1 + p2 + p3) * cal_interval4 +
    strata(event_order) +
    cluster(equipment)
)

fit_pwp_gt_tv <- coxph(form_gt_tv, data = df_tv, ties = "efron")
summary(fit_pwp_gt_tv)
## Call:
## coxph(formula = Surv(start_gt, stop_gt, status) ~ d1 + d2 + d3 + 
##     d4 + d5 + p1 + p2 + p3 + cal_interval4 + strata(event_order) + 
##     d1:cal_interval4 + d2:cal_interval4 + d3:cal_interval4 + 
##     d4:cal_interval4 + d5:cal_interval4 + p1:cal_interval4 + 
##     p2:cal_interval4 + p3:cal_interval4, data = df_tv, ties = "efron", 
##     cluster = equipment)
## 
##   n= 6412, number of events= 6412 
## 
##                               coef  exp(coef)   se(coef)  robust se      z
## d1                      -0.2141420  0.8072337  0.3392866  0.1808961 -1.184
## d2                       0.1679933  1.1829287  0.2841880  0.3143783  0.534
## d3                      -0.1588208  0.8531493  0.0698437  0.0682713 -2.326
## d4                      -0.1679335  0.8454101  0.0732890  0.0766060 -2.192
## d5                      -0.0611987  0.9406363  0.1097452  0.0979682 -0.625
## p1                       0.1362330  1.1459489  0.0788674  0.0766248  1.778
## p2                      -0.0001564  0.9998436  0.0610926  0.0513441 -0.003
## p3                       0.1835470  1.2014714  0.1684674  0.0973863  1.885
## cal_interval4Q4_2024    -0.2853474  0.7517530  0.0655687  0.0792357 -3.601
## cal_interval4Q1_2025    -0.5040617  0.6040721  0.0685484  0.0894079 -5.638
## cal_interval4Q2_2025    -0.6078132  0.5445404  0.0705488  0.0907712 -6.696
## d1:cal_interval4Q4_2024 -0.0163238  0.9838087  0.4510959  0.3056123 -0.053
## d1:cal_interval4Q1_2025 -0.0837809  0.9196327  0.4373875  0.3198410 -0.262
## d1:cal_interval4Q2_2025 -1.2584322  0.2840991  0.6799865  0.4657233 -2.702
## d2:cal_interval4Q4_2024 -0.6099597  0.5433727  0.4231985  0.5249778 -1.162
## d2:cal_interval4Q1_2025  0.0836979  1.0873003  0.3583106  0.5433764  0.154
## d2:cal_interval4Q2_2025 -0.2294096  0.7950028  0.4015424  0.3846385 -0.596
## d3:cal_interval4Q4_2024 -0.0508935  0.9503799  0.0963145  0.0917627 -0.555
## d3:cal_interval4Q1_2025 -0.0724035  0.9301555  0.0988453  0.1088910 -0.665
## d3:cal_interval4Q2_2025 -0.0927890  0.9113858  0.0960576  0.0896248 -1.035
## d4:cal_interval4Q4_2024 -0.0200480  0.9801517  0.1019346  0.1064305 -0.188
## d4:cal_interval4Q1_2025  0.0693768  1.0718400  0.0970716  0.1082046  0.641
## d4:cal_interval4Q2_2025  0.0303311  1.0307958  0.0986969  0.0993338  0.305
## d5:cal_interval4Q4_2024 -0.0696815  0.9326908  0.1493201  0.1532793 -0.455
## d5:cal_interval4Q1_2025  0.0446781  1.0456912  0.1491046  0.1395457  0.320
## d5:cal_interval4Q2_2025 -0.0266760  0.9736766  0.1438545  0.1429170 -0.187
## p1:cal_interval4Q4_2024 -0.2827991  0.7536712  0.1166694  0.1398628 -2.022
## p1:cal_interval4Q1_2025 -0.3404903  0.7114214  0.1346882  0.1968493 -1.730
## p1:cal_interval4Q2_2025 -0.2986517  0.7418177  0.1299465  0.1572072 -1.900
## p2:cal_interval4Q4_2024 -0.1219246  0.8852151  0.0836602  0.0888352 -1.372
## p2:cal_interval4Q1_2025 -0.0833683  0.9200122  0.0810994  0.0892318 -0.934
## p2:cal_interval4Q2_2025  0.0391287  1.0399043  0.0811575  0.0895767  0.437
## p3:cal_interval4Q4_2024 -0.0184044  0.9817639  0.2176371  0.2182787 -0.084
## p3:cal_interval4Q1_2025  0.0066461  1.0066683  0.2078511  0.1491779  0.045
## p3:cal_interval4Q2_2025 -0.5671852  0.5671195  0.2394397  0.2020950 -2.807
##                         Pr(>|z|)    
## d1                      0.236498    
## d2                      0.593088    
## d3                      0.020002 *  
## d4                      0.028367 *  
## d5                      0.532182    
## p1                      0.075416 .  
## p2                      0.997569    
## p3                      0.059466 .  
## cal_interval4Q4_2024    0.000317 ***
## cal_interval4Q1_2025    1.72e-08 ***
## cal_interval4Q2_2025    2.14e-11 ***
## d1:cal_interval4Q4_2024 0.957403    
## d1:cal_interval4Q1_2025 0.793363    
## d1:cal_interval4Q2_2025 0.006890 ** 
## d2:cal_interval4Q4_2024 0.245285    
## d2:cal_interval4Q1_2025 0.877584    
## d2:cal_interval4Q2_2025 0.550889    
## d3:cal_interval4Q4_2024 0.579154    
## d3:cal_interval4Q1_2025 0.506104    
## d3:cal_interval4Q2_2025 0.300527    
## d4:cal_interval4Q4_2024 0.850589    
## d4:cal_interval4Q1_2025 0.521417    
## d4:cal_interval4Q2_2025 0.760103    
## d5:cal_interval4Q4_2024 0.649394    
## d5:cal_interval4Q1_2025 0.748841    
## d5:cal_interval4Q2_2025 0.851932    
## p1:cal_interval4Q4_2024 0.043179 *  
## p1:cal_interval4Q1_2025 0.083684 .  
## p1:cal_interval4Q2_2025 0.057468 .  
## p2:cal_interval4Q4_2024 0.169914    
## p2:cal_interval4Q1_2025 0.350155    
## p2:cal_interval4Q2_2025 0.662244    
## p3:cal_interval4Q4_2024 0.932805    
## p3:cal_interval4Q1_2025 0.964465    
## p3:cal_interval4Q2_2025 0.005008 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
##                         exp(coef) exp(-coef) lower .95 upper .95
## d1                         0.8072     1.2388    0.5663    1.1507
## d2                         1.1829     0.8454    0.6388    2.1906
## d3                         0.8531     1.1721    0.7463    0.9753
## d4                         0.8454     1.1829    0.7275    0.9824
## d5                         0.9406     1.0631    0.7763    1.1398
## p1                         1.1459     0.8726    0.9861    1.3316
## p2                         0.9998     1.0002    0.9041    1.1057
## p3                         1.2015     0.8323    0.9927    1.4541
## cal_interval4Q4_2024       0.7518     1.3302    0.6436    0.8781
## cal_interval4Q1_2025       0.6041     1.6554    0.5070    0.7198
## cal_interval4Q2_2025       0.5445     1.8364    0.4558    0.6506
## d1:cal_interval4Q4_2024    0.9838     1.0165    0.5405    1.7908
## d1:cal_interval4Q1_2025    0.9196     1.0874    0.4913    1.7213
## d1:cal_interval4Q2_2025    0.2841     3.5199    0.1140    0.7078
## d2:cal_interval4Q4_2024    0.5434     1.8404    0.1942    1.5204
## d2:cal_interval4Q1_2025    1.0873     0.9197    0.3748    3.1541
## d2:cal_interval4Q2_2025    0.7950     1.2579    0.3741    1.6896
## d3:cal_interval4Q4_2024    0.9504     1.0522    0.7939    1.1376
## d3:cal_interval4Q1_2025    0.9302     1.0751    0.7514    1.1514
## d3:cal_interval4Q2_2025    0.9114     1.0972    0.7646    1.0864
## d4:cal_interval4Q4_2024    0.9802     1.0203    0.7956    1.2075
## d4:cal_interval4Q1_2025    1.0718     0.9330    0.8670    1.3251
## d4:cal_interval4Q2_2025    1.0308     0.9701    0.8484    1.2523
## d5:cal_interval4Q4_2024    0.9327     1.0722    0.6907    1.2595
## d5:cal_interval4Q1_2025    1.0457     0.9563    0.7955    1.3746
## d5:cal_interval4Q2_2025    0.9737     1.0270    0.7358    1.2884
## p1:cal_interval4Q4_2024    0.7537     1.3268    0.5730    0.9914
## p1:cal_interval4Q1_2025    0.7114     1.4056    0.4837    1.0464
## p1:cal_interval4Q2_2025    0.7418     1.3480    0.5451    1.0095
## p2:cal_interval4Q4_2024    0.8852     1.1297    0.7438    1.0536
## p2:cal_interval4Q1_2025    0.9200     1.0869    0.7724    1.0958
## p2:cal_interval4Q2_2025    1.0399     0.9616    0.8725    1.2395
## p3:cal_interval4Q4_2024    0.9818     1.0186    0.6400    1.5059
## p3:cal_interval4Q1_2025    1.0067     0.9934    0.7515    1.3485
## p3:cal_interval4Q2_2025    0.5671     1.7633    0.3816    0.8427
## 
## Concordance= 0.558  (se = 0.006 )
## Likelihood ratio test= 298.9  on 35 df,   p=<2e-16
## Wald test            = 263.1  on 35 df,   p=<2e-16
## Score (logrank) test = 299.3  on 35 df,   p=<2e-16,   Robust = 92.6  p=4e-07
## 
##   (Note: the likelihood ratio and score tests assume independence of
##      observations within a cluster, the Wald and robust score tests do not).
# ===============================================================
# 9 UJI SIGNIFIKANSI PARSIAL (WALD TEST + HR)
# ===============================================================

coef_final <- tidy(fit_pwp_gt_tv, exponentiate = TRUE, conf.int = TRUE)
print(coef_final)
## # A tibble: 35 × 8
##    term        estimate std.error robust.se statistic p.value conf.low conf.high
##    <chr>          <dbl>     <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
##  1 d1             0.807    0.339     0.181   -1.18    2.36e-1    0.566     1.15 
##  2 d2             1.18     0.284     0.314    0.534   5.93e-1    0.639     2.19 
##  3 d3             0.853    0.0698    0.0683  -2.33    2.00e-2    0.746     0.975
##  4 d4             0.845    0.0733    0.0766  -2.19    2.84e-2    0.728     0.982
##  5 d5             0.941    0.110     0.0980  -0.625   5.32e-1    0.776     1.14 
##  6 p1             1.15     0.0789    0.0766   1.78    7.54e-2    0.986     1.33 
##  7 p2             1.00     0.0611    0.0513  -0.00305 9.98e-1    0.904     1.11 
##  8 p3             1.20     0.168     0.0974   1.88    5.95e-2    0.993     1.45 
##  9 cal_interv…    0.752    0.0656    0.0792  -3.60    3.17e-4    0.644     0.878
## 10 cal_interv…    0.604    0.0685    0.0894  -5.64    1.72e-8    0.507     0.720
## # ℹ 25 more rows
# ===============================================================
# 10 BASELINE HAZARD MODEL AKHIR
# ===============================================================

base_haz <- basehaz(fit_pwp_gt_tv)
## Warning in survfit.coxph(fit, se.fit = FALSE): the model contains interactions;
## the default curve based on columm means of the X matrix is almost certainly not
## useful. Consider adding a newdata argument.
head(base_haz)
##        hazard time        strata
## 1 0.005328507  1.2 event_order=1
## 2 0.010681344  1.3 event_order=1
## 3 0.016058512  4.8 event_order=1
## 4 0.021447949  6.3 event_order=1
## 5 0.026851756  9.0 event_order=1
## 6 0.032295439 10.8 event_order=1
haz_rate <- diff(base_haz$hazard) / diff(base_haz$time)
head(haz_rate)
## [1] 0.053528374 0.001536333 0.003592958 0.002001410 0.003024268 0.003127702