A Compact Letter Display (CLD) is a statistical visualization technique used to summarize the outcomes of multiple pairwise comparisons, often following an ANOVA. It assigns letters to groups so that those sharing the same letter are not significantly different, while groups without overlapping letters are statistically distinct. This method is widely applied in research because it provides a clear, concise, and easily interpretable ranking of differences.
library(agricolae)
library(ggplot2)
library(readxl)
library(car)
## Warning: package 'car' was built under R version 4.3.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.3.2
library(multcompView)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:car':
##
## recode
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
data_tebu <- read_excel("I:/My Drive/pak eka/Tebu/Tebu rekap th 1 dan 2/Pertumbuhanfisiologidantanah.xlsx")
data_tebu <- data.frame(data_tebu)
data_tebu$Perlakuan <- as.factor(data_tebu$Perlakuan)
data_tebu$Lokasi <- as.factor(data_tebu$Lokasi)
data_tebu$Blok <- as.factor(data_tebu$Blok)
model <- aov(Chltot ~ Blok + Perlakuan*Lokasi, data = data_tebu)
cat("===== ANOVA =====\n")
## ===== ANOVA =====
print(summary(model))
## Df Sum Sq Mean Sq F value Pr(>F)
## Blok 2 0.0687 0.0343 0.828 0.441056
## Perlakuan 4 0.6415 0.1604 3.867 0.006634 **
## Lokasi 2 0.7591 0.3795 9.152 0.000284 ***
## Perlakuan:Lokasi 8 0.1947 0.0243 0.587 0.785517
## Residuals 73 3.0274 0.0415
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("\n===== ANOVA =====\n")
##
## ===== ANOVA =====
anova_table <- Anova(model)
print(anova_table)
## Anova Table (Type II tests)
##
## Response: Chltot
## Sum Sq Df F value Pr(>F)
## Blok 0.06866 2 0.8278 0.4410556
## Perlakuan 0.64148 4 3.8669 0.0066341 **
## Lokasi 0.75908 2 9.1517 0.0002841 ***
## Perlakuan:Lokasi 0.19473 8 0.5869 0.7855173
## Residuals 3.02744 73
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Ambil p-value
p_perlakuan <- anova_table["Perlakuan", "Pr(>F)"]
p_lokasi <- anova_table["Lokasi", "Pr(>F)"]
p_interaksi <- anova_table["Perlakuan:Lokasi", "Pr(>F)"]
cat("\n===== UJI NORMALITAS =====\n")
##
## ===== UJI NORMALITAS =====
shapiro <- shapiro.test(residuals(model))
print(shapiro)
##
## Shapiro-Wilk normality test
##
## data: residuals(model)
## W = 0.9913, p-value = 0.8222
cat("\n===== KOEFISIEN VARIASI =====\n")
##
## ===== KOEFISIEN VARIASI =====
cv <- cv.model(model)
print(cv)
## [1] 17.72802
cat("\n===== TUKEY INTERAKSI =====\n")
##
## ===== TUKEY INTERAKSI =====
tukey_interaksi <- HSD.test(model, c("Perlakuan","Lokasi"), group=TRUE)
print(tukey_interaksi)
## $statistics
## MSerror Df Mean CV MSD
## 0.04147183 73 1.148726 17.72802 0.412714
##
## $parameters
## test name.t ntr StudentizedRange alpha
## Tukey Perlakuan:Lokasi 15 4.964188 0.05
##
## $means
## Chltot std r Min Max Q25 Q50
## P1:Jogja 1.3011425 0.3100000 6 1.0380000 1.906000 1.1528964 1.2046800
## P1:Lampung 1.0662412 0.2831909 6 0.7290000 1.454000 0.8321656 1.1472023
## P1:Sidoarjo 1.0719959 0.1407018 6 0.8890000 1.231547 0.9571513 1.1033026
## P2:Jogja 1.4980052 0.2673649 6 1.2219270 1.897000 1.3329607 1.3926173
## P2:Lampung 1.2050177 0.2417494 6 0.8900000 1.517000 1.0571431 1.1707272
## P2:Sidoarjo 1.1310683 0.1628781 6 0.9307143 1.296477 1.0117500 1.1395000
## P3:Jogja 1.2510288 0.2044012 6 1.0308942 1.517545 1.0740501 1.2505000
## P3:Lampung 1.1891969 0.0780820 6 1.1079489 1.304000 1.1299885 1.1724771
## P3:Sidoarjo 1.1534083 0.0945739 6 1.0310000 1.248531 1.0845000 1.1575744
## P4:Jogja 1.1570971 0.1092100 6 1.0161205 1.280000 1.0785974 1.1555000
## P4:Lampung 1.0297394 0.1700942 6 0.7380000 1.237956 0.9985000 1.0293806
## P4:Sidoarjo 1.0613027 0.2028594 6 0.7330000 1.342000 0.9947229 1.0869486
## P5:Jogja 1.1782625 0.1722347 6 1.0200039 1.494841 1.0785000 1.1213650
## P5:Lampung 1.0176214 0.1283306 6 0.8260000 1.165420 0.9426482 1.0301541
## P5:Sidoarjo 0.9197597 0.2858427 6 0.4150000 1.216685 0.8347500 0.9969759
## Q75
## P1:Jogja 1.289565
## P1:Lampung 1.181467
## P1:Sidoarjo 1.173118
## P2:Jogja 1.676250
## P2:Lampung 1.389459
## P2:Sidoarjo 1.268164
## P3:Jogja 1.393750
## P3:Lampung 1.239959
## P3:Sidoarjo 1.238614
## P4:Jogja 1.250749
## P4:Lampung 1.123980
## P4:Sidoarjo 1.137940
## P5:Jogja 1.216182
## P5:Lampung 1.112929
## P5:Sidoarjo 1.083429
##
## $comparison
## NULL
##
## $groups
## Chltot groups
## P2:Jogja 1.4980052 a
## P1:Jogja 1.3011425 ab
## P3:Jogja 1.2510288 ab
## P2:Lampung 1.2050177 ab
## P3:Lampung 1.1891969 ab
## P5:Jogja 1.1782625 ab
## P4:Jogja 1.1570971 ab
## P3:Sidoarjo 1.1534083 ab
## P2:Sidoarjo 1.1310683 ab
## P1:Sidoarjo 1.0719959 b
## P1:Lampung 1.0662412 b
## P4:Sidoarjo 1.0613027 b
## P4:Lampung 1.0297394 b
## P5:Lampung 1.0176214 b
## P5:Sidoarjo 0.9197597 b
##
## attr(,"class")
## [1] "group"
data_summary <- data_tebu %>%
group_by(Perlakuan, Lokasi) %>%
summarise(
mean = mean(Chltot, na.rm = TRUE),
sd = sd(Chltot, na.rm = TRUE),
.groups = "drop"
)
if(p_perlakuan < 0.05){
tukey_P <- HSD.test(model, "Perlakuan", group=TRUE)
huruf_P <- tukey_P$groups
huruf_P$Perlakuan <- rownames(huruf_P)
huruf_P <- huruf_P %>%
mutate(huruf_P = toupper(groups)) %>%
select(Perlakuan, huruf_P)
} else {
huruf_P <- data.frame(
Perlakuan = levels(data_tebu$Perlakuan),
huruf_P = ""
)
}
if(p_lokasi < 0.05){
tukey_L <- HSD.test(model, "Lokasi", group=TRUE)
huruf_L <- tukey_L$groups
huruf_L$Lokasi <- rownames(huruf_L)
huruf_L <- huruf_L %>%
mutate(huruf_L = tolower(groups)) %>%
select(Lokasi, huruf_L)
} else {
huruf_L <- data.frame(
Lokasi = levels(data_tebu$Lokasi),
huruf_L = ""
)
}
data_summary <- data_summary %>%
left_join(huruf_P, by="Perlakuan") %>%
left_join(huruf_L, by="Lokasi")
if(p_interaksi < 0.05){
data_summary$star <- "*"
} else {
data_summary$star <- ""
}
data_summary$label_signif <- paste0(
data_summary$huruf_P,
data_summary$huruf_L,
data_summary$star
)
ggplot(data_summary,
aes(x = Perlakuan,
y = mean,
fill = Lokasi)) +
geom_bar(stat = "identity",
position = position_dodge(0.9),
alpha = 0.85) +
geom_errorbar(aes(ymin = mean - sd,
ymax = mean + sd),
width = 0.2,
position = position_dodge(0.9)) +
geom_text(aes(label = label_signif,
y = mean + sd + 0.05*max(mean)),
position = position_dodge(0.9),
size = 3,
fontface = "bold") +
labs(x = "Perlakuan",
y = "Klorofil Total (mg/g)",
fill = "Lokasi") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 12))