The AccSamplingDesign package provides tools for designing and evaluating Acceptance Sampling plans for quality control in manufacturing and inspection settings. It supports both attributes and variables sampling methods with a focus on minimizing producer’s and consumer’s risks.
Install the stable release from CRAN:
Or install from GitHub
Load package
Note that we could use method optPlan() or optAttrPlan(), both work the same.
summary(plan_attr)
#> Attributes Acceptance Sampling Plan
#> -----------------------------------
#> Distribution: binomial
#> Sample Size (n): 144
#> Acceptance Number (c): 4
#> Producer's Risk (PR = 0.01534843 ) at PRQ = 0.01
#> Consumer's Risk (CR = 0.1487162 ) at CRQ = 0.05
#> ----------------------------------
# Step1: Find an optimal Attributes Sampling plan
optimal_plan <- optPlan(PRQ = 0.01, CRQ = 0.05, alpha = 0.02, beta = 0.15,
distribution = "binomial") # could try "poisson" too
# Summarize the plan
summary(optimal_plan)
#> Attributes Acceptance Sampling Plan
#> -----------------------------------
#> Distribution: binomial
#> Sample Size (n): 144
#> Acceptance Number (c): 4
#> Producer's Risk (PR = 0.01534843 ) at PRQ = 0.01
#> Consumer's Risk (CR = 0.1487162 ) at CRQ = 0.05
#> ----------------------------------
# Step2: Compare the optimal plan with two alternative plans
pd <- seq(0, 0.15, by = 0.001)
oc_opt <- OCdata(plan = optimal_plan, pd = pd)
oc_alt1 <- OCdata(n = optimal_plan$n, c = optimal_plan$c - 1,
distribution = "binomial", pd = pd)
oc_alt2 <- OCdata(n = optimal_plan$n, c = optimal_plan$c + 1,
distribution = "binomial", pd = pd)
# Step3: Visualize results
plot(pd, oc_opt@paccept, type = "l", col = "blue", lwd = 2,
xlab = "Proportion Defective", ylab = "Probability of Acceptance",
main = "Attributes Sampling - OC Curves Comparison",
xlim = c(0, 0.15), ylim = c(0, 1))
lines(pd, oc_alt1@paccept, col = "red", lwd = 2, lty = 2)
lines(pd, oc_alt2@paccept, col = "green", lwd = 2, lty = 3)
abline(v = c(0.01, 0.05), col = "gray50", lty = 2)
abline(h = c(1 - 0.02, 0.15), col = "gray50", lty = 2)
legend("topright", legend = c(sprintf("Optimal Plan (n = %d, c = %d)",
optimal_plan$n, optimal_plan$c),
sprintf("Alt 1 (c = %d)", optimal_plan$c - 1),
sprintf("Alt 2 (c = %d)", optimal_plan$c + 1)),
col = c("blue", "red", "green"),
lty = c(1, 2, 3), lwd = 2)
Note that we could use method optPlan() or optVarPlan(), both work the same.
# Predefine parameters
PRQ <- 0.025
CRQ <- 0.1
alpha <- 0.05
beta <- 0.1
norm_plan <- optPlan(
PRQ = PRQ, # Acceptable quality level (% nonconforming)
CRQ = CRQ, # Rejectable quality level (% nonconforming)
alpha = alpha, # Producer's risk
beta = beta, # Consumer's risk
distribution = "normal",
sigma_type = "known"
)
# Summary plan
summary(norm_plan)
#> Variables Acceptance Sampling Plan
#> ----------------------------------
#> Distribution: normal
#> Sample Size (n): 19
#> Acceptability Constant (k): 1.579
#> Population Standard Deviation: known
#> Producer's Risk (PR = 0.05 ) at PRQ = 0.025
#> Consumer's Risk (CR = 0.1 ) at CRQ = 0.1
#> ----------------------------------
# Probability of accepting 10% defective
accProb(norm_plan, 0.1)
#> [1] 0.1
# plot OC
plot(norm_plan)
# Setup a pd range to make sure all plans have use same pd range
pd <- seq(0, 0.2, by = 0.001)
# Generate OC curve data for designed plan
opt_pdata <- OCdata(norm_plan, pd = pd)
# Evaluated Plan 1: n + 6
eval1_pdata <- OCdata(n = norm_plan$n + 6, k = norm_plan$k,
distribution = "normal", pd = pd)
# Evaluated Plan 2: k + 0.1
eval2_pdata <- OCdata(n = norm_plan$n, k = norm_plan$k + 0.1,
distribution = "normal", pd = pd)
# Plot base
plot(100 * opt_pdata@pd, 100 * opt_pdata@paccept,
type = "l", lwd = 2, col = "blue",
xlab = "Percentage Nonconforming (%)",
ylab = "Probability of Acceptance (%)",
main = "Normal Variables Sampling - Designed Plan with Evaluated Plans")
# Add evaluated plan 1: n + 6
lines(100 * eval1_pdata@pd, 100 * eval1_pdata@paccept,
col = "red", lty = "longdash", lwd = 2)
# Add evaluated plan 2: k + 0.1
lines(100 * eval2_pdata@pd, 100 * eval2_pdata@paccept,
col = "forestgreen", lty = "dashed", lwd = 2)
# Add vertical dashed lines at PRQ and CRQ
abline(v = 100 * PRQ, col = "gray60", lty = "dashed")
abline(v = 100 * CRQ, col = "gray60", lty = "dashed")
# Add horizontal dashed lines at 1 - alpha and beta
abline(h = 100 * (1 - alpha), col = "gray60", lty = "dashed")
abline(h = 100 * beta, col = "gray60", lty = "dashed")
# Add legend
legend("topright",
legend = c(paste0("Designed Plan: n = ", norm_plan$sample_size, ", k = ", round(norm_plan$k, 2)),
"Evaluated Plan: n + 6",
"Evaluated Plan: k + 0.1"),
col = c("blue", "red", "forestgreen"),
lty = c("solid", "longdash", "dashed"),
lwd = 2,
bty = "n")
p1 = 0.005
p2 = 0.03
alpha = 0.05
beta = 0.1
# known sigma plan
plan1 <- optPlan(
PRQ = p1, # Acceptable quality level (% nonconforming)
CRQ = p2, # Rejectable quality level (% nonconforming)
alpha = alpha, # Producer's risk
beta = beta, # Consumer's risk
distribution = "normal",
sigma_type = "know")
summary(plan1)
#> Variables Acceptance Sampling Plan
#> ----------------------------------
#> Distribution: normal
#> Sample Size (n): 18
#> Acceptability Constant (k): 2.185
#> Population Standard Deviation: known
#> Producer's Risk (PR = 0.05 ) at PRQ = 0.005
#> Consumer's Risk (CR = 0.1 ) at CRQ = 0.03
#> ----------------------------------
plot(plan1)
# unknown sigma plan
plan2 <- optPlan(
PRQ = p1, # Acceptable quality level (% nonconforming)
CRQ = p2, # Rejectable quality level (% nonconforming)
alpha = alpha, # Producer's risk
beta = beta, # Consumer's risk
distribution = "normal",
sigma_type = "unknow")
summary(plan2)
#> Variables Acceptance Sampling Plan
#> ----------------------------------
#> Distribution: normal
#> Sample Size (n): 62
#> Acceptability Constant (k): 2.192
#> Population Standard Deviation: unknown
#> Producer's Risk (PR = 0.05 ) at PRQ = 0.005
#> Consumer's Risk (CR = 0.1 ) at CRQ = 0.03
#> ----------------------------------
plot(plan2)
beta_plan <- optPlan(
PRQ = 0.05, # Target quality level (% nonconforming)
CRQ = 0.2, # Minimum quality level (% nonconforming)
alpha = 0.05, # Producer's risk
beta = 0.1, # Consumer's risk
distribution = "beta",
theta = 44000000,
theta_type = "known",
LSL = 0.00001
)
# Summary Beta plan
summary(beta_plan)
#> Variables Acceptance Sampling Plan
#> ----------------------------------
#> Distribution: beta
#> Sample Size (n): 14
#> Acceptability Constant (k): 1.186
#> Population Precision Parameter (theta): known
#> Producer's Risk (PR = 0.04999589 ) at PRQ = 0.05
#> Consumer's Risk (CR = 0.09947491 ) at CRQ = 0.2
#> Lower Specification Limit (LSL): 1e-05
#> ----------------------------------
# Probability of accepting 5% defective
accProb(beta_plan, 0.05)
#> [1] 0.9500041
# Plot OC use plot function
plot(beta_plan)
The Probability of Acceptance (Pa) is given by: Pa(p) = \sum_{i=0}^c
\binom{n}{i}p^i(1-p)^{n-i}
where:
The Probability of Acceptance (Pa) is given by:
Pa(p) = \Phi\left( -\sqrt{n_{\sigma}} \cdot (\Phi^{-1}(p) + k_{\sigma}) \right)
Or we could write:
Pa(p) = 1 - \Phi\left( \sqrt{n_{\sigma}} \cdot (\Phi^{-1}(p) + k_{\sigma}) \right)
where:
The required sample size (n_{\sigma}) and acceptability constant (k_{\sigma}) are: n_{\sigma} = \left( \frac{\Phi^{-1}(1 - \alpha) + \Phi^{-1}(1 - \beta)}{\Phi^{-1}(1 - PRQ) - \Phi^{-1}(1 - CRQ)} \right)^2
k_{\sigma} = \frac{\Phi^{-1}(1 - PRQ) \cdot \Phi^{-1}(1 - \beta) + \Phi^{-1}(1 - CRQ) \cdot \Phi^{-1}(1 - \alpha)}{\Phi^{-1}(1 - \alpha) + \Phi^{-1}(1 - \beta)} where:
The formula for the probability of acceptance (Pa) is:
Pa(p) = \Phi \left( \sqrt{\frac{n_s}{1 + \frac{k_s^2}{2}}} \left( \Phi^{-1}(1 - p) - k_s \right) \right)
where:
k_s = k_{\sigma} is the acceptability constant.
n_s: This is the adjusted sample size when the sample standard deviation s (instead of population \sigma) is used for estimation. It accounts for the additional variability due to estimation:
n_s = n_{\sigma} \times \left( 1 + \frac{k_s^2}{2} \right)
(See Wilrich, PT. (2004) for more detail about calculation used in sessions 6.2 and 6.3)
Traditional acceptance sampling using normal distributions can be inadequate for compositional data bounded within [0,1]. Govindaraju and Kissling (2015) proposed Beta-based plans, where component proportions (e.g., protein content) follow X \sim \text{Beta}(a, b), with density:
f(x; a, b) = \frac{x^{a-1} (1 - x)^{b-1}}{B(a, b)},
where B(a, b) is the Beta function. The distribution is reparameterized via mean \mu and precision \theta:
\mu = \frac{a}{a + b}, \quad \theta = a + b, \quad \sigma^2 \approx \frac{\mu(1 - \mu)}{\theta} \quad (\text{for large } \theta).
Higher \theta reduces variance, concentrating values around \mu. The probability of acceptance (Pa) parallels normal-based plans:
Pa = P(\mu - k \sigma \geq L \mid \mu, \theta, m, k),
where L is the lower specification limit, m is the sample size, and k is the acceptability constant. Parameters m and k ensure:
Pa(\mu_{PRQ}) = 1 - \alpha, \quad Pa(\mu_{CRQ}) = \beta,
with \alpha (producer’s risk) and \beta (consumer’s risk) at specified quality levels (PRQ/CRQ).
Note that: this problem is solved to find m and k used Non-linear programming.
For a nonconforming proportion p (e.g.,PRQ or CRQ), the mean \mu at a quality level (PRQ/CRQ) is derived by solving:
P(X \leq L \mid \mu, \theta) = p,
where X \sim \text{Beta}(\theta \mu, \theta (1 - \mu)). This links \mu to p via the Beta cumulative distribution function (CDF) at L.
For a beta distribution, the required sample size m_s (unknown \theta) is derived from the known-\theta sample size m_\theta using the formula:
m_s = \left(1 + 0.85k^2\right)m_\theta
where k is unchanged. This
adjustment accounts for the variance ratio R
= \frac{\text{Var}(S)}{\text{Var}(\hat{\mu})}, which quantifies
the relative variability of the sample standard deviation S compared to the estimator \hat{\mu}. Unlike the normal
distribution, where \text{Var}(S) \approx
\frac{\sigma^2}{2n}, for beta distribution’s, the ratio R depends on \mu, \theta, and sample size m. The conservative factor 0.85k^2 approximates this ratio for
practical use (see Govindaraju and Kissling (2015) )