Here are two methods to label the limits. The limit values seem to be mislabeled in your data, by the way. I much prefer the second method because placing the text is hard to do in a way that works in all cases.
library(ggplot2)
library(dplyr, warn.conflicts = FALSE)
library(tidyr)
DF <- structure(list(process_attribute = c("Yield (%)", "Yield (%)",
"Plates at Column Pack", "Plates at Column Pack", "Asymmetry at Column Pack",
"Asymmetry at Column Pack", "Eluate Concentration (mg/mL)", "Eluate Concentration (mg/mL)",
"Eluate Volume (CV)", "Eluate Volume (CV)", "Eluate pH", "Eluate pH",
"Eluate Conductivity (mS/cm)", "Eluate Conductivity (mS/cm)"),
name = c("eng_1", "eng_2", "eng_1", "eng_2", "eng_1", "eng_2",
"eng_1", "eng_2", "eng_1", "eng_2", "eng_1", "eng_2", "eng_1",
"eng_2"),
value = c(90, 72, 1005, 804, 1, 0.8, 14, 11.2,
4, 3.2, 4.5, 3.6, 3, 2.4),
type = c("KPA", "KPA", "KPA", "KPA", "KPA", "KPA", "KPA", "KPA", "PA", "PA", "PA", "PA",
"PA", "PA"),
data_normal = c("Yes", "Yes", "No", "No", "No","No", "Yes", "Yes", "Yes", "Yes", "No", "No", "No", "No"),
ppk = c(7.7, 7.7, NA, NA, NA, NA, 2.94, 2.94, NA, NA, NA,
NA, NA, NA),
upper_limit = c(NA, NA, NA, NA, 0.8, 0.8, 4.7,
4.7, 1.1, 1.1, 4.25, 4.25, 0.4, 0.4),
lower_limit = c(70,70, 1000, 1000, 1.6, 1.6, 20.6, 20.6, 3.7, 3.7, 4.64, 4.64,
3.2, 3.2),
upper_control_limit = c(NA, NA, NA, NA, NA, NA,8.6, 8.6, NA, NA, NA, NA, NA, NA),
lower_control_limit = c(82,82, NA, NA, NA, NA, 12.9, 12.9, NA, NA, NA, NA, NA, NA)),
row.names = c(NA, -14L), class = c("tbl_df", "tbl", "data.frame"))
DF %>%
ggplot(aes(name, value)) +
geom_point(size = 5) +
geom_hline(aes(yintercept = upper_limit)) +
geom_hline(aes(yintercept = lower_limit)) +
geom_text(aes(x = 0.7, y = upper_limit), label = "UCL", size = 3, vjust = -0.3) +
geom_text(aes(x = 0.7, y = lower_limit), label = "LCL", size = 3, vjust = 1) +
facet_wrap(~process_attribute, scales = "free" ) +
labs(x = "Batch", y = "Value") +
theme_light()
#> Warning: Removed 4 rows containing missing values (geom_hline).
#> Warning: Removed 4 rows containing missing values (geom_text).

Limits <- DF %>% select(process_attribute, upper_limit, lower_limit) %>%
pivot_longer(cols = c("upper_limit", "lower_limit"), names_to = "LimitType") %>%
unique()
DF %>%
ggplot(aes(name, value)) +
geom_point(size = 5) +
geom_hline(aes(yintercept = value, color = LimitType), data = Limits) +
facet_wrap(~process_attribute, scales = "free" ) +
labs(x = "Batch", y = "Value") +
theme_light()
#> Warning: Removed 2 rows containing missing values (geom_hline).

Created on 2021-03-30 by the reprex package (v0.3.0)