This file contains an example of the function
mvogammaDPD. It reproduces all the figures and tables in
section “Application: Analyzing Ultramarathon Race Performances” of A.
Ghosh, C. Agostinelli and A. Basu (2026) A Composite Divergence Approach
to Robust Multivariate Estimation under Cellwise and Casewise
Contamination, arXiv:2608.18914, https://arxiv.org/abs/2608.18914.
The dataset was obtained from the publicly available data on the website www.kaggle.com/datasets/fatihyavuzz/two-centuries-of-um-races which contains ace results from ultramarathon events held worldwide over approximately two centuries.
We restrict to mens’ 50-mile races. For each race event (identified by the event name and date), finishing times were converted to hours and the ten fastest finishers were retained, producing one ordered \(10\)-dimensional observation per race. Events with fewer than ten recorded finishers or with tied finishing times among the top ten were discarded, yielding a collection of complete ordered observations of 4683 races.
##
## Attaching package: 'tidyr'
## The following object is masked from 'package:reshape2':
##
## smiths
## The following object is masked from 'package:cellWise':
##
## unpack
data("twocenturies50")
ordered_data <- twocenturies50[order(twocenturies50[,1]),]
n <- nrow(twocenturies50)
p <- ncol(twocenturies50)min_val <- min(best0, best1, best2)
max_val <- max(best0, best1, best2)
heatplot <- function(mat) {
df <- melt(mat)
colnames(df) <- c("Event", "FinishingTime", "Hours")
df$FinishingTime <- as.numeric(as.factor(df$FinishingTime))
ggplot(df, aes(FinishingTime, Event, fill = Hours)) +
geom_tile() +
scale_x_continuous(
breaks = 1:10,
labels = 1:10,
expand = expansion(mult = c(0.01, 0.01))
) +
scale_y_discrete(
expand = expansion(mult = c(0.03, 0.03))
) +
scale_fill_gradient2(
low = "blue",
mid = "white",
high = "red",
midpoint = (min_val + max_val) / 2,
limits = c(min_val, max_val),
breaks = round(seq(min_val, max_val, length.out = 5),0)
) +
labs(
x = "Top 10 Finishing Times",
y = "Events",
fill = "Hours"
) +
theme_classic(base_size = 14)
}perform.analysis <- function(x) {
# Maximum likelihood
ml <- mvogammaML(x=x, method="multivariate",
initial=list(delta=c(18, rep(0.5, 9)), lambda=5))
# Maximum composite likelihood (minimum CDPD with beta=0)
cml <- mvogammaML(x=x, method="composite",
initial=list(delta=ml$delta, lambda=ml$lambda))
# Minimum composite DPD
cdpd1 <- mvogammaDPD(x=x, beta=0.1, method="composite",
initial=list(delta=ml$delta, lambda=ml$lambda))
cdpd2 <- mvogammaDPD(x=x, beta=0.2, method="composite",
initial=list(delta=ml$delta, lambda=ml$lambda))
cdpd3 <- mvogammaDPD(x=x, beta=0.3, method="composite",
initial=list(delta=ml$delta, lambda=ml$lambda))
cdpd5 <- mvogammaDPD(x=x, beta=0.5, method="composite",
initial=list(delta=ml$delta, lambda=ml$lambda))
# Minimum (multivariate) DPD
mdpd1 <- mvogammaDPD(x=x, beta=0.1, method="multivariate",
initial=list(delta=ml$delta, lambda=ml$lambda))
mdpd2 <- mvogammaDPD(x=x, beta=0.2, method="multivariate",
initial=list(delta=ml$delta, lambda=ml$lambda))
mdpd3 <- mvogammaDPD(x=x, beta=0.3, method="multivariate",
initial=list(delta=ml$delta, lambda=ml$lambda))
mdpd5 <- mvogammaDPD(x=x, beta=0.5, method="multivariate",
initial=list(delta=ml$delta, lambda=ml$lambda))
results.multivariate <- cbind(
c(ml$delta, ml$lambda),
c(mdpd1$delta, mdpd1$lambda),
c(mdpd2$delta, mdpd2$lambda),
c(mdpd3$delta, mdpd3$lambda),
c(mdpd5$delta, mdpd5$lambda)
)
results.composite <- cbind(
c(cml$delta, cml$lambda),
c(cdpd1$delta, cdpd1$lambda),
c(cdpd2$delta, cdpd2$lambda),
c(cdpd3$delta, cdpd3$lambda),
c(cdpd5$delta, cdpd5$lambda)
)
colnames(results.multivariate) <- c("ML", "DPD(0.1)", "DPD(0.2)",
"DPD(0.3)", "DPD(0.5)")
colnames(results.composite) <- c("CML", "CDPD(0.1)", "CDPD(0.2)",
"CDPD(0.3)", "CDPD(0.5)")
rownames(results.multivariate) <- c(paste0("delta", 1:10), "lambda")
rownames(results.composite) <- rownames(results.multivariate)
res <- list(MDPDE=results.multivariate, MCDPDE=results.composite)
return(res)
}results0 <- perform.analysis(best0)
results1 <- perform.analysis(best1)
results2 <- perform.analysis(best2)# Define the methods (X-axis categories) in the exact order from the image
methods <- c("ML", "CML", "DPD(0.1)", "DPD(0.2)", "DPD(0.3)",
"DPD(0.5)", "CDPD(0.1)", "CDPD(0.2)", "CDPD(0.3)", "CDPD(0.5)")
mybarplot <- function(X1, X2) {
# Create a data frame with the extracted percentages
df <- data.frame(Method = factor(methods, levels = methods),
Row_1 = X1, Row_2 = X2)
# Convert data to long format for ggplot2
df_long <- pivot_longer(df, cols = c(Row_1, Row_2),
names_to = "Parameter", values_to = "Percentage")
# Create the Plot
p <- ggplot(df_long, aes(x = Method, y = Percentage, fill = Parameter)) +
# Add grouped bars with black outlines
# Matching position_dodge width and bar width removes the inner gap
geom_bar(
stat = "identity",
position = position_dodge(width = 0.8), # Changed from 0.85
color = "black",
width = 0.8, # Changed from 0.75 to match dodge width
linewidth = 0.6
) +
# Add data labels on top of the bars
geom_text(
aes(label = sprintf("%.0f", Percentage)),
position = position_dodge(width = 0.8), # Must match the dodge width in geom_bar
vjust = -0.5,
size = 4,
color = "black"
) +
# Map colors and use mathematical expressions for the legend labels (lambda and delta)
scale_fill_manual(
values = c("Row_1" = "#4C72B0", "Row_2" = "#DD8452"),
labels = c(expression(lambda), expression(delta[1]))
) +
# Configure Y-axis: force origin at 0 and set max limit slightly above data
scale_y_continuous(
limits = c(0, max(df_long$Percentage) * 1.15),
breaks = seq(0, 100, 20),
expand = expansion(mult = c(0, 0))
) +
# Axis and Legend Labels
labs(
x = "Estimation Method",
y = "Absolute relative changes (in %)",
fill = "Parameter"
) +
# Theme Modifications
theme_classic(base_size = 14) +
theme(
# Axis tick values bold and larger
axis.text.x = element_text(angle = 45, hjust = 1, color = "black", size = 14, face = "bold"),
axis.text.y = element_text(color = "black", size = 14, face = "bold"),
# Axis titles
axis.title = element_text(face = "bold", size = 16),
axis.line = element_line(color = "black", linewidth = 0.7),
axis.ticks = element_line(color = "black", linewidth = 0.7),
# Legend formatting
legend.position = c(0.88, 0.88),
legend.background = element_rect(fill = "white", color = NA),
legend.box.background = element_rect(color = "black", linewidth = 0.5),
legend.title = element_text(face = "bold", size = 14),
legend.text = element_text(size = 15),
# Plot margins
plot.margin = margin(t = 15, r = 15, b = 10, l = 10)
)
# Display the plot
print(p)
}## Warning in data.frame(Method = factor(methods, levels = methods), Row_1 = X1, :
## row names were found from a short variable and have been discarded
## Warning in data.frame(Method = factor(methods, levels = methods), Row_1 = X1, :
## row names were found from a short variable and have been discarded
| ML | DPD(0.1) | DPD(0.2) | DPD(0.3) | DPD(0.5) | CML | CDPD(0.1) | CDPD(0.2) | CDPD(0.3) | CDPD(0.5) | |
|---|---|---|---|---|---|---|---|---|---|---|
| delta1 | 35.5937929 | 47.5632934 | 55.4770158 | 57.1681314 | 85.2730287 | 37.2687001 | 43.7593157 | 50.3258019 | 55.8767889 | 63.1306796 |
| delta2 | 1.3727117 | 1.3113695 | 1.1431913 | 0.9323130 | 0.5909875 | 1.5180410 | 1.6523939 | 1.7781186 | 1.8720803 | 1.9621139 |
| delta3 | 1.0620231 | 1.1174047 | 1.0635492 | 0.9350123 | 0.5892075 | 1.1137143 | 1.2535921 | 1.3815005 | 1.4783155 | 1.5865120 |
| delta4 | 0.9595409 | 0.9773686 | 0.9669776 | 0.9156475 | 1.6750364 | 0.9532154 | 1.0460214 | 1.1336777 | 1.2025272 | 1.2811915 |
| delta5 | 0.8816706 | 0.9569257 | 0.9840510 | 0.9582662 | 1.4560956 | 0.8271594 | 0.9164400 | 1.0027796 | 1.0717456 | 1.1532131 |
| delta6 | 0.8861077 | 0.9459913 | 0.9675964 | 0.9386188 | 0.8380347 | 0.8058590 | 0.9025761 | 0.9935286 | 1.0654555 | 1.1509209 |
| delta7 | 0.8175404 | 0.8643808 | 0.8881577 | 0.9013135 | 2.4540202 | 0.7457256 | 0.8304402 | 0.9120202 | 0.9781022 | 1.0592739 |
| delta8 | 0.7580196 | 0.8313041 | 0.8502355 | 0.7951094 | 0.5876140 | 0.6682450 | 0.7542774 | 0.8364581 | 0.9026133 | 0.9845109 |
| delta9 | 0.7672345 | 0.8051608 | 0.8127383 | 0.7725575 | 0.5889167 | 0.6698725 | 0.7467534 | 0.8223565 | 0.8835308 | 0.9593029 |
| delta10 | 0.7567449 | 0.7612948 | 0.7606741 | 0.7503468 | 0.7395887 | 0.6953653 | 0.7578130 | 0.8212529 | 0.8710231 | 0.9291434 |
| lambda | 11.5272861 | 15.5548295 | 18.3712500 | 19.1444287 | 27.3492173 | 11.9365827 | 14.0126824 | 16.1170649 | 17.9008320 | 20.2443890 |
| ML | DPD(0.1) | DPD(0.2) | DPD(0.3) | DPD(0.5) | CML | CDPD(0.1) | CDPD(0.2) | CDPD(0.3) | CDPD(0.5) | |
|---|---|---|---|---|---|---|---|---|---|---|
| delta1 | 18.0192523 | 47.8143091 | 55.5464007 | 56.8379668 | 85.3310842 | 7.8325930 | 39.9103882 | 49.8146071 | 55.2221500 | 61.2740569 |
| delta2 | 0.7698542 | 1.2564433 | 1.1008747 | 0.9075394 | 0.5909242 | 0.3688863 | 1.4328984 | 1.6443228 | 1.7210093 | 1.7773748 |
| delta3 | 0.6735827 | 1.0949291 | 1.0436298 | 0.9198889 | 0.5892038 | 0.2989162 | 1.1226493 | 1.3257939 | 1.4159213 | 1.4963618 |
| delta4 | 0.6020602 | 0.9580732 | 0.9557754 | 0.9096475 | 1.6758740 | 0.2578770 | 0.9410788 | 1.0947518 | 1.1638678 | 1.2340627 |
| delta5 | 0.5776649 | 0.9550089 | 0.9875142 | 0.9602607 | 1.4575121 | 0.2368911 | 0.8414102 | 0.9821623 | 1.0494165 | 1.1211363 |
| delta6 | 0.5784387 | 0.9618857 | 0.9849749 | 0.9451675 | 0.8385376 | 0.2289897 | 0.8299240 | 0.9827797 | 1.0569518 | 1.1361240 |
| delta7 | 0.5330029 | 0.8526394 | 0.8815506 | 0.8982681 | 2.4571987 | 0.2203913 | 0.7502061 | 0.8797155 | 0.9426386 | 1.0118011 |
| delta8 | 0.5399201 | 0.8465783 | 0.8527836 | 0.7894589 | 0.5876756 | 0.2243305 | 0.7157576 | 0.8479096 | 0.9164131 | 0.9922036 |
| delta9 | 0.5363224 | 0.8104838 | 0.8146358 | 0.7690818 | 0.5889927 | 0.2329905 | 0.7011945 | 0.8220302 | 0.8851415 | 0.9577589 |
| delta10 | 0.5299473 | 0.7691254 | 0.7673829 | 0.7531313 | 0.7398518 | 0.2604165 | 0.7243400 | 0.8285250 | 0.8787054 | 0.9317627 |
| lambda | 5.1246558 | 15.7137708 | 18.4768953 | 19.0852188 | 27.3724585 | 2.1824415 | 12.8200050 | 16.0382931 | 17.7877824 | 19.7588087 |
| ML | DPD(0.1) | DPD(0.2) | DPD(0.3) | DPD(0.5) | CML | CDPD(0.1) | CDPD(0.2) | CDPD(0.3) | CDPD(0.5) | |
|---|---|---|---|---|---|---|---|---|---|---|
| delta1 | 0.2498760 | 0.2704943 | 0.2952131 | 0.0063546 | 1.3461534 | 0.2513854 | 0.2700291 | 0.4071065 | 0.1371442 | 0.1329020 |
| delta2 | 0.2927930 | 0.2605365 | 0.2620843 | 0.3691824 | 0.2104163 | 0.4388801 | 0.3053431 | 0.3022508 | 0.1822355 | 0.0803819 |
| delta3 | 0.3635870 | 0.3175717 | 0.2812998 | 0.4634006 | 0.1228359 | 0.4863957 | 0.6945053 | 59.9700493 | 19.3326694 | 0.4417919 |
| delta4 | 0.3410185 | 0.3328679 | 0.2952049 | 0.3760686 | 0.1394769 | 0.2220891 | 0.2643207 | 1.4287564 | 1.1649873 | 45.2624485 |
| delta5 | 0.3384358 | 0.3673984 | 0.3604647 | 0.3532245 | 1743.1405670 | 0.1662756 | 0.2078227 | 1.3855875 | 0.1661685 | 42.4477761 |
| delta6 | 0.3159736 | 0.3598314 | 0.4309145 | 588.9708158 | 1.2864590 | 0.1371503 | 0.1852244 | 1.2091556 | 0.1731099 | 2.4047794 |
| delta7 | 0.3139827 | 0.3512311 | 0.3921932 | 4.9440803 | 18.6369872 | 0.1291231 | 0.1779783 | 1.2285557 | 0.1586679 | 0.1338800 |
| delta8 | 0.3024390 | 0.3451335 | 0.3971786 | 34.3352194 | 36.7160706 | 0.1261642 | 0.1769319 | 1.0891819 | 0.6468224 | 2.5825714 |
| delta9 | 0.2887453 | 0.3228545 | 0.3486171 | 1.1761314 | 43.6180167 | 0.1293902 | 0.1832293 | 0.9860158 | 0.5666844 | 0.2266257 |
| delta10 | 0.2869471 | 0.3255191 | 0.3664096 | 4.4787093 | 20.7763514 | 0.1482400 | 0.2054014 | 0.9359451 | 0.4861150 | 0.2279680 |
| lambda | 0.8165636 | 0.6756489 | 0.6075678 | 181.2831030 | 634.4833983 | 0.5221463 | 0.5552243 | 18.5703908 | 5.8164414 | 25.9485088 |