diff --git a/R/commonQualityControl.R b/R/commonQualityControl.R index dfadf14d..c9304b0b 100644 --- a/R/commonQualityControl.R +++ b/R/commonQualityControl.R @@ -10,27 +10,27 @@ # Function to create the x-bar and r-chart section .qcXbarAndRContainer <- function(options, dataset, ready, jaspResults, measurements, subgroups, wideFormat) { - + if (!is.null(jaspResults[["controlCharts"]])) return() - + container <- createJaspContainer(title = gettext("Control Chart")) container$dependOn(options = c("controlChartsType", "report", "measurementsWideFormat", "subgroup", "measurementLongFormat", "manualSubgroupSizeValue", "manualSubgroupSize", "manualTicksXAxis", "manualTicksXAxisValue", "xBarAndRChart", "xmrChart")) container$position <- 1 jaspResults[["controlCharts"]] <- container - + matrixPlot <- createJaspPlot(title = "X-bar & R control chart", width = 1200, height = 550) container[["plot"]] <- matrixPlot - + if (!ready) return() - + if (length(measurements) < 2) { matrixPlot$setError(gettext("Subgroup size must be > 1 to display X-bar & R Chart.")) return() } - + plotMat <- matrix(list(), 2, 1) plotMat[[1,1]] <- .Xbarchart(dataset = dataset[measurements], options = options, manualXaxis = subgroups, warningLimits = FALSE, Wide = wideFormat, manualTicks = options[["manualTicksXAxis"]])$p @@ -60,7 +60,7 @@ controlLimitsPerGroup = FALSE) { data <- dataset[, unlist(lapply(dataset, is.numeric))] decimals <- max(.decimalplaces(data)) - sdType <- match.arg(sdType) + sdType <- match.arg(sdType) if(Phase2) { mu <- as.numeric(target) sigma <- as.numeric(sd) @@ -70,15 +70,15 @@ sigma <- .sdXbar(df = data, type = sdType) } sixsigma <- qcc::qcc(data, type ='xbar', plot = FALSE, center = mu, sizes = ncol(data), std.dev = sigma) - + #calculate group sizes n <- apply(data, 1, function(x) return(sum(!is.na(x)))) # returns the number of non NA values per row if (!controlLimitsPerGroup) # if control limits are not calculated per group they are based on largest group size n <- max(n) - + if (length(sixsigma$statistics) == 1) OnlyOutofLimit <- TRUE # other rules don't apply if only 1 group - + if (!identical(manualSubgroups, "")) { subgroups <- manualSubgroups } else { @@ -104,7 +104,7 @@ LWL1 <- WL1$LCL UWL2 <- WL2$UCL LWL2 <- WL2$LCL - + # arrange data for CL in df cl_plot <- data.frame(LCL = LCL, UCL = UCL, center = center, subgroups = subgroups, UWL1 = UWL1, LWL1 = LWL1, UWL2 = UWL2, LWL2 = LWL2) @@ -119,8 +119,8 @@ LWL2 = cl_plot$LWL2[nrow(cl_plot)] )) cl_plot$subgroups[-1] <- cl_plot$subgroups[-1] - .5 - - + + if (!identical(manualDataYaxis, "")) { manualMeans <- rowMeans(manualDataYaxis) yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(LCL, UCL, manualMeans)) @@ -134,12 +134,12 @@ nxBreaks <- 5 xBreaks <- c(1,jaspGraphs::getPrettyAxisBreaks(subgroups, n = nxBreaks)[-1]) xLimits <- c(1, max(xBreaks) * 1.15) - + # get (one of) the most frequent centers, LCL and UCL to display them centerDisplay <- as.numeric(names(sort(-table(center)))[1]) LCLDisplay <- as.numeric(names(sort(-table(LCL)))[1]) UCLDisplay <- as.numeric(names(sort(-table(UCL)))[1]) - + dfLabel <- data.frame( x = max(xLimits) * 0.95, y = c(centerDisplay, UCLDisplay, LCLDisplay), @@ -149,14 +149,14 @@ gettextf("LCL = %g", round(LCLDisplay, decimals + 2)) ) ) - + p <- ggplot2::ggplot(data_plot, ggplot2::aes(x = subgroups, y = means)) + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = UCL), col = "red", size = 1.5, linetype = "dashed") + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = LCL), col = "red", size = 1.5, linetype = "dashed") + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = center), col = "green", size = 1) - + if (warningLimits) { p <- p + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = UWL1), col = "orange", size = 1, linetype = "dashed") + @@ -173,7 +173,7 @@ p <- p + ggplot2::scale_y_continuous(name = ggplot2::element_blank(), limits = yLimits, breaks = yBreaks, labels = NULL) + ggplot2::theme(axis.line.y = ggplot2::element_blank(), axis.ticks.y = ggplot2::element_blank()) } - + if(smallLabels){ labelSize <- 3.5 pointsSize <- 3 @@ -181,15 +181,15 @@ labelSize <- 4.5 pointsSize <- 4 } - + if (plotLimitLabels) p <- p + ggplot2::geom_label(data = dfLabel, ggplot2::aes(x = x, y = y, label = l),inherit.aes = FALSE, size = labelSize) - + p <- p + ggplot2::scale_x_continuous(name = gettext(xAxisLab), breaks = xBreaks, limits = range(xLimits)) + jaspGraphs::geom_line(color = "blue") + jaspGraphs::geom_rangeframe() + jaspGraphs::themeJaspRaw(fontsize = jaspGraphs::setGraphOption("fontsize", 15)) - + # Out of control red dots marking if (Phase2) p <- p + jaspGraphs::geom_point(size = pointsSize, fill = ifelse(NelsonLaws(sixsigma)$red_points, "red", "blue")) @@ -197,29 +197,29 @@ p <- p + jaspGraphs::geom_point(size = pointsSize, fill = ifelse(data_plot$means > UCL | data_plot$means < LCL, "red", "blue")) else p <- p + jaspGraphs::geom_point(size = pointsSize, fill = ifelse(NelsonLaws(sixsigma, allsix = TRUE)$red_points, "red", "blue")) - + # if more than half of the dots are violations, do not show red dots. n.outOfLimits <- sum(data_plot$means > UCL , data_plot$means < LCL) if ( n.outOfLimits > (nrow(data_plot) / 2) ) p <- p + jaspGraphs::geom_point(size = pointsSize, fill = "blue") - + if (!identical(manualXaxis, "")) { if (GaugeRR | Wide){ xBreaks_Out <- manualXaxis p <- p + ggplot2::scale_x_continuous(breaks = xBreaks, labels = xBreaks_Out[xBreaks]) } else { - + xBreaks_Out <- unique(manualXaxis) # use unique to preserve original order unlike levels xLabels <- xBreaks_Out[xBreaks] xLimits <- c(range(xBreaks)[1], range(xBreaks)[2] * 1.15) p <- p + ggplot2::scale_x_continuous(name = xAxisLab, breaks = xBreaks, labels = xLabels, limits = xLimits) } } - - + + if (title != "") p <- p + ggplot2::ggtitle(title) - + if (!identical(manualXaxis, "")) return(list(p = p, sixsigma = sixsigma, xLabels = as.vector(xBreaks_Out))) else return(list(p = p, sixsigma = sixsigma)) @@ -231,16 +231,16 @@ xAxisLab = gettext("Subgroup"), manualDataYaxis = "", manualXaxis = "", title = "", smallLabels = FALSE, OnlyOutofLimit = FALSE, GaugeRR = FALSE, Wide = FALSE, manualTicks = FALSE, controlLimitsPerGroup = FALSE) { - + #remove rows with single observation as no meaningful range and no CL can be computed rowRemovalIndex <- which(apply(dataset, 1, function(x) sum(!is.na(x)) < 2)) #get index of rows with less than 2 obs. if (length(rowRemovalIndex) != 0) dataset <- dataset[-rowRemovalIndex, ] - + #Arrange data and compute decimals data <- dataset[, unlist(lapply(dataset, is.numeric))] decimals <- max(.decimalplaces(data)) - + n <- apply(data, 1, function(x) return(sum(!is.na(x)))) # returns the number of non NA values per row if (!controlLimitsPerGroup) # if control limits are not calculated per group they are based on largest group size n <- max(n) @@ -249,15 +249,15 @@ d2 <- sapply(n, function(x) KnownControlStats.RS(x, 0)$constants[1]) mu <- sigma * d2 sixsigma <- qcc::qcc(data, type ='R', plot = FALSE, center = mu, std.dev = sigma, sizes = ncol(data)) - + if (length(sixsigma$statistics) == 1) OnlyOutofLimit <- TRUE # other rules don't apply if only 1 group - + if(Phase2 && sd != "") sixsigma <- list(statistics = sixsigma$statistics, limits = KnownControlStats.RS(sixsigma$sizes[1], as.numeric(sd))$limits, center = KnownControlStats.RS(sixsigma$sizes[1], as.numeric(sd))$center) - + range <- sixsigma$statistics if (!identical(manualSubgroups, "")) { subgroups <- manualSubgroups @@ -269,7 +269,7 @@ LCL <- manualLimits[1] center <- manualLimits[2] UCL <- manualLimits[3] - }else{ + }else{ limits <- .controlLimits(mu, sigma, n = n, type = "r") center <- mu UCL <- limits$UCL @@ -283,8 +283,8 @@ center = cl_plot$center[nrow(cl_plot)], subgroups = cl_plot$subgroups[nrow(cl_plot)] + 1)) cl_plot$subgroups[-1] <- cl_plot$subgroups[-1] - .5 - - + + if (!identical(manualDataYaxis, "")) { manualRange <- apply(manualDataYaxis, 1, function(x) max(x) - min(x)) yBreaks <- jaspGraphs::getPrettyAxisBreaks(c(LCL, UCL, manualRange)) @@ -302,7 +302,7 @@ centerDisplay <- as.numeric(names(sort(-table(center)))[1]) LCLDisplay <- as.numeric(names(sort(-table(LCL)))[1]) UCLDisplay <- as.numeric(names(sort(-table(UCL)))[1]) - + dfLabel <- data.frame( x = max(xLimits) * 0.95, y = c(centerDisplay, UCLDisplay, LCLDisplay), @@ -312,14 +312,14 @@ gettextf("LCL = %g", round(LCLDisplay, decimals + 2)) ) ) - + p <- ggplot2::ggplot(data_plot, ggplot2::aes(x = subgroups, y = range)) + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = UCL), col = "red", size = 1.5, linetype = "dashed") + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = LCL), col = "red", size = 1.5, linetype = "dashed") + ggplot2::geom_step(data = cl_plot, mapping = ggplot2::aes(x = subgroups, y = center), col = "green", size = 1) - + if (yAxis){ p <- p + ggplot2::scale_y_continuous(name = gettext(yAxisLab) ,limits = yLimits, breaks = yBreaks) }else{ @@ -327,7 +327,7 @@ ggplot2::scale_y_continuous(name = ggplot2::element_blank() ,limits = yLimits, breaks = yBreaks, labels = NULL) + ggplot2::theme(axis.line.y = ggplot2::element_blank(), axis.ticks.y = ggplot2::element_blank()) } - + if(smallLabels){ labelSize <- 3.5 pointsSize <- 3 @@ -337,12 +337,12 @@ } if (plotLimitLabels) p <- p + ggplot2::geom_label(data = dfLabel, ggplot2::aes(x = x, y = y, label = l), inherit.aes = FALSE, size = labelSize) - + p <- p + ggplot2::scale_x_continuous(name= gettext(xAxisLab), breaks = xBreaks, limits = range(xLimits)) + jaspGraphs::geom_line(color = "blue") + jaspGraphs::geom_rangeframe() + jaspGraphs::themeJaspRaw(fontsize = jaspGraphs::setGraphOption("fontsize", 15)) - + if (!identical(manualXaxis, "")) { if (GaugeRR | Wide){ xBreaks_Out <- manualXaxis @@ -355,34 +355,34 @@ p <- p + ggplot2::scale_x_continuous(name = xAxisLab, breaks = xBreaks, labels = xLabels, limits = xLimits) } } - + if (OnlyOutofLimit) p <- p + jaspGraphs::geom_point(size = pointsSize, fill = ifelse(data_plot$range > UCL | data_plot$range < LCL, "red", "blue")) else p <- p + jaspGraphs::geom_point(size = pointsSize, fill = ifelse(NelsonLaws(sixsigma)$red_points, "red", "blue")) - + # if more than half of the dots are violations, do not show red dots. n.outOfLimits <- sum(data_plot$range > UCL , data_plot$range < LCL) if ( n.outOfLimits > (nrow(data_plot) / 2) ) p <- p + jaspGraphs::geom_point(size = pointsSize, fill = "blue") - + if (title != "") p <- p + ggplot2::ggtitle(title) - + if (!identical(manualXaxis, "")) return(list(p = p, sixsigma = sixsigma, xLabels = as.vector(xBreaks_Out))) else return(list(p = p, sixsigma = sixsigma)) } NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { - + # Adjust Rules to SKF pars <- Rspc::SetParameters() pars$Rule2$nPoints = 7 pars$Rule3$nPoints = 7 pars$Rule3$convention = "minitab" pars$Rule4$convention = "minitab" - + #Evaluate all rules if (chart == "p") { n = length(data$statistics) @@ -396,7 +396,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { warnings <- Rspc::EvaluateRules(x = data$statistics, type = chart, lcl = data$limits[1,1], ucl = data$limits[1,2], cl = data$center[1], parRules = pars, whichRules = c(1:3,5,7:8)) } - + if (allsix) { if (length(xLabels) == 0) { Rules <- list(R1 = which(warnings[,2] == 1), @@ -429,41 +429,41 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { } red_points = apply(warnings[,c(2,3,4)], 1, sum) > 0 } - + return(list(red_points = red_points, Rules = Rules)) } .NelsonTable <- function(dataset, options, sixsigma, type = "xbar", Phase2 = TRUE, name = "X-bar", xLabels = NULL) { - + table <- createJaspTable(title = gettextf("Test results for %s chart", name)) - + if (length(sixsigma$statistics) == 1) # no need for table with only 1 group return(table) - + if (!Phase2 || type == "xbar.one") { - + Test <- NelsonLaws(data = sixsigma, allsix = TRUE, xLabels = xLabels) - + if (length(Test$Rules$R1) > 0) table$addColumnInfo(name = "test1", title = gettextf("Test 1: Beyond limit") , type = "integer") - + if (length(Test$Rules$R2) > 0) table$addColumnInfo(name = "test2", title = gettextf("Test 2: Shift") , type = "integer") - + if (length(Test$Rules$R3) > 0) table$addColumnInfo(name = "test3", title = gettextf("Test 3: Trend") , type = "integer") - + if (length(Test$Rules$R4) > 0) table$addColumnInfo(name = "test4", title = gettextf("Test 4: Increasing variation") , type = "integer") - + if (length(Test$Rules$R5) > 0) table$addColumnInfo(name = "test5", title = gettextf("Test 5: Reducing variation") , type = "integer") - + if (length(Test$Rules$R6) > 0) table$addColumnInfo(name = "test6", title = gettextf("Test 6: Bimodal distribution") , type = "integer") - - - + + + table$setData(list( "test1" = c(Test$Rules$R1), "test2" = c(Test$Rules$R2), @@ -472,26 +472,26 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { "test5" = c(Test$Rules$R5), "test6" = c(Test$Rules$R6) )) - + } else { - + if (name == "np" || name == "c" || name == "u" || name == "Laney p'" || name == "Laney u'") Test <- NelsonLaws(data = sixsigma, xLabels = xLabels, chart = "c") else if (name == "P") Test <- NelsonLaws(data = sixsigma, xLabels = xLabels, chart = "p") else Test <- NelsonLaws(data = sixsigma, xLabels = xLabels) - + if (length(Test$Rules$R1) > 0) table$addColumnInfo(name = "test1", title = gettextf("Test 1: Beyond limit") , type = "integer") - + if (length(Test$Rules$R2) > 0) table$addColumnInfo(name = "test2", title = gettextf("Test 2: Shift") , type = "integer") - + if (length(Test$Rules$R3) > 0) table$addColumnInfo(name = "test3", title = gettextf("Test 3: Trend") , type = "integer") - + if (type == "Range" & length(xLabels) == 0){ table$setData(list( "test1" = c(Test$Rules$R1 + 1), @@ -506,7 +506,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { )) } } - + table$showSpecifiedColumnsOnly <- TRUE table$addFootnote(message = gettext("Numbers are data points where test violations occur.")) return(table) @@ -517,7 +517,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { if (length(sixsigma$statistics) == 1) # no need for table with only 1 group return(violationsList) - + if (!Phase2 || type == "xbar.one") { Test <- NelsonLaws(data = sixsigma, allsix = TRUE, xLabels = xLabels) violationsList[["test1"]] <- Test$Rules$R1 @@ -533,9 +533,9 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { Test <- NelsonLaws(data = sixsigma, xLabels = xLabels, chart = "p") else Test <- NelsonLaws(data = sixsigma, xLabels = xLabels) - + if (type == "Range") { - Test$Rules$R1 <- Test$Rules$R1 + 1 + Test$Rules$R1 <- Test$Rules$R1 + 1 Test$Rules$R2 <- Test$Rules$R2 + 1 Test$Rules$R3 <- Test$Rules$R3 + 1 } @@ -562,27 +562,27 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { .IMRchart <- function(dataset, options, variable = "", measurements = "", cowPlot = FALSE, manualXaxis = "", Wide = FALSE, stages = "") { - + ppPlot <- createJaspPlot(width = 900, height = 650) tableI <- createJaspTable(title = gettextf("Test results for individuals chart")) tableR <- createJaspTable(title = gettextf("Test results for range chart")) if (!identical(stages, "")) { nStages <- length(unique(dataset[[stages]])) - + # Error conditions for stages - if(any(table(dataset[[stages]]) < options[["movingRangeLength"]])) { + if(any(table(dataset[[stages]]) < options[["xmrChartMovingRangeLength"]])) { ppPlot$setError(gettext("Moving range length is larger than one of the stages.")) return(list(p = ppPlot)) - } + } } else { nStages <- 1 dataset$stage <- 1 stages <- "stage" } - + ppPlot$width <- 900 + nStages * 100 - + # Calculate values per subplot/stage dataPlotI <- data.frame(matrix(ncol = 7, nrow = 0)) dataPlotR <- data.frame(matrix(ncol = 7, nrow = 0)) @@ -601,7 +601,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { if (identical(measurements, "") && !identical(variable, "")) { ppPlot$dependOn(optionContainsValue = list(variables = variable)) data <- data.frame(process = dataForPlot[[variable]]) - k <- options[["movingRangeLength"]] + k <- options[["xmrChartMovingRangeLength"]] # qcc has no moving range plot, so we need to arrange data in a matrix with the observation + k future observation per row and calculate the range chart mrMatrix <- matrix(data$process[1:(length(data$process) - (k - 1))]) # remove last k - 1 elements for (j in 2:k) { @@ -614,7 +614,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { sixsigma_R <- qcc::qcc(mrMatrix, type = "R", plot = FALSE, std.dev = sd) } else { data <- as.vector((t(dataForPlot[measurements]))) - k <- options[["movingRangeLength"]] + k <- options[["xmrChartMovingRangeLength"]] sd <- qcc::sd.xbar.one(data, k = k) sixsigma_I <- qcc::qcc(data, type ='xbar.one', plot = FALSE, std.dev = sd) # qcc has no moving range plot, so we need to arrange data in a matrix with the observation + k future observation per row and calculate the range chart @@ -698,7 +698,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { tableRList[[i]] <- lapply(tableRList[[i]], "length<-", max(lengths(tableRList[[i]]))) # this fills up all elements of the list with NAs so all elements are the same size } } - + # filling up tables for individuals and moving range charts tableIListVectorized <- unlist(tableIList, recursive = FALSE) tableILongestVector <- max(sapply(tableIListVectorized, length)) @@ -758,7 +758,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { )) tableR$showSpecifiedColumnsOnly <- TRUE } - + # Calculations that apply to the whole plot yBreaks1 <- jaspGraphs::getPrettyAxisBreaks(c(dataPlotI$process, dataPlotI$LCL, dataPlotI$UCL, dataPlotI$center)) yBreaks2 <- jaspGraphs::getPrettyAxisBreaks(c(dataPlotR$movingRange, dataPlotR$LCL, dataPlotR$UCL, dataPlotR$center)) @@ -775,7 +775,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { if (xBreaks2[1] == 0) xBreaks2[1] <- 1 xLimits <- c(min(xBreaks1), max(xBreaks1) * 1.15) - + # Create plots ## individual plots p1 <- ggplot2::ggplot(dataPlotI, ggplot2::aes(x = subgroup, y = process, group = stage)) + @@ -791,7 +791,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { jaspGraphs::geom_point(size = 4, fill = dataPlotI$dotColor, inherit.aes = TRUE) + jaspGraphs::geom_rangeframe() + jaspGraphs::themeJaspRaw() - + ## moving range plots p2 <- ggplot2::ggplot(dataPlotR, ggplot2::aes(x = subgroup, y = movingRange, group = stage)) + ggplot2::geom_vline(xintercept = seperationLinesR) + @@ -807,7 +807,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { jaspGraphs::geom_point(size = 4, fill = dataPlotR$dotColor, inherit.aes = TRUE) + jaspGraphs::geom_rangeframe() + jaspGraphs::themeJaspRaw() - + if (!identical(manualXaxis, "")) { if (!identical(measurements, "")) { if (Wide) @@ -817,21 +817,21 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { } else xLabels <- manualXaxis - + p1 <- p1 + ggplot2::scale_x_continuous(breaks = xBreaks1, labels = xLabels[xBreaks1]) p2 <- p2 + ggplot2::scale_x_continuous(breaks = xBreaks2, labels = xLabels[xBreaks2]) } - + plotMat <- matrix(data = list(), nrow = 2, ncol = 1) plotMat[[1,1]] <- p1 plotMat[[2,1]] <- p2 - + if(!cowPlot){ ppPlot$plotObject <- jaspGraphs::ggMatrixPlot(plotList = plotMat, removeXYlabels= "x") } else { ppPlot$plotObject <- cowplot::plot_grid(plotlist = plotMat, nrow = 2) } - + if (!identical(manualXaxis, "")) return(list(p = ppPlot, sixsigma_I = sixsigma_I, sixsigma_R = sixsigma_R, xLabels = as.vector(xLabels), p1 = p1, p2 = p2, tableI = tableI, tableR = tableR)) else @@ -849,7 +849,7 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { sdWithin <- mean(rowSd, na.rm = TRUE) } return(sdWithin) -} +} .rowRanges <- function(df) { nrow <- nrow(df) @@ -866,19 +866,19 @@ NelsonLaws <- function(data, allsix = FALSE, chart = "i", xLabels = NULL) { } KnownControlStats.RS <- function(N, sigma) { - + Data.d3 <- data.frame( n = 2:25, d3 = c(0.8525 ,0.8884, 0.8798, 0.8641, 0.8480, 0.8332, 0.8198, 0.8078, 0.7971, 0.7873, 0.7785, 0.7704, 0.7630, 0.7562, 0.7499, 0.7441, 0.7386, 0.7335, 0.7287, 0.7242, 0.7199, 0.7159, 0.7121, 0.7084)) - + Data.d2 <- data.frame( n = 2:50, d2 = c( 1.128, 1.693 ,2.059, 2.326, 2.534, 2.704, 2.847, 2.970, 3.078, 3.173, 3.258, 3.336, 3.407, 3.472, 3.532, 3.588 ,3.640 ,3.689, 3.735, 3.778, 3.819, 3.858, 3.895, 3.931, 3.964, 3.997, 4.027, 4.057, 4.086, 4.113, 4.139 ,4.165 ,4.189, 4.213, 4.236, 4.259, 4.280, 4.301, 4.322, 4.341, 4.361, 4.379, 4.398, 4.415, 4.433, 4.450 ,4.466, 4.482, 4.498)) - + if (N > 25 && N <= 50){ d3 <- 0.80818 - 0.0051871 * N + 0.00005098 * N^2 - 0.00000019 * N^3 d2 <- Data.d2[N == Data.d2$n,2] @@ -889,14 +889,14 @@ KnownControlStats.RS <- function(N, sigma) { d2 <- Data.d2[N == Data.d2$n,2] d3 <- Data.d3[N == Data.d3$n,2] } - + c4 <- sqrt(2/(N-1)) * gamma(N/2) / gamma((N-1)/2) c5 <- sqrt(1 - c4^2) - + UCL <- d2 * sigma + 3 * d3 * sigma CL <- d2 * sigma LCL <- max(0, d2 * sigma - 3 * d3 * sigma) - + return(list(constants = c(d2, d3, c4, c5), limits = data.frame(LCL,UCL), center = CL)) } diff --git a/R/processCapabilityStudies.R b/R/processCapabilityStudies.R index 3a717e0c..bc59cf3c 100644 --- a/R/processCapabilityStudies.R +++ b/R/processCapabilityStudies.R @@ -1417,7 +1417,7 @@ processCapabilityStudies <- function(jaspResults, dataset, options) { if (!ready) return() Container <- createJaspContainer(gettextf("X-mR control chart")) - Container$dependOn(options = c("xBarAndRChart", "measurementsWideFormat", "subgroup", "measurementLongFormat", "manualSubgroupSizeValue", "report", "movingRangeLength")) + Container$dependOn(options = c("xBarAndRChart", "measurementsWideFormat", "subgroup", "measurementLongFormat", "manualSubgroupSizeValue", "report", "xmrChartMovingRangeLength")) Container$position <- 1 jaspResults[["ImR Charts"]] <- Container Container[["plot"]] <- .IMRchart(dataset = dataset, measurements = measurements, options = options, manualXaxis = subgroups, cowPlot = TRUE, Wide = wideFormat)$p diff --git a/R/variablesChartsIndividuals.R b/R/variablesChartsIndividuals.R index 59dda60f..5e7bc49a 100644 --- a/R/variablesChartsIndividuals.R +++ b/R/variablesChartsIndividuals.R @@ -18,9 +18,9 @@ #' @export variablesChartsIndividuals <- function(jaspResults, dataset, options) { # reading variables in from the GUI - variables <- unlist(options$variables) - stages <- unlist(options$split) - subgroups <- unlist(options$subgroups) + variables <- unlist(options[["measurement"]]) + stages <- unlist(options[["stage"]]) + subgroups <- unlist(options[["axisLabels"]]) makeSplit <- subgroups != "" numeric_variables <- variables @@ -51,16 +51,16 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { #Checking for errors in the dataset .hasErrors(dataset, type = c('infinity', 'missingValues', "observations"), - infinity.target = c(options$variables, options$subgroups), - missingValues.target = c(options$variables, options$subgroups), + infinity.target = c(options[["measurement"]], options[["axisLabels"]]), + missingValues.target = c(options[["measurement"]], options[["axisLabels"]]), observations.amount = c("< 2"), - observations.target = c(options$variables), + observations.target = c(options[["measurement"]]), exitAnalysisIfErrors = TRUE) - if (options$ImRchart && length(variables) == 0) { + if (options[["xmrChart"]] && length(variables) == 0) { plot <- createJaspPlot(title = gettext("Individuals Charts"), width = 700, height = 400) jaspResults[["plot"]] <- plot - plot$dependOn(c("ImRchart", "variables", "subgroups", "split")) + plot$dependOn(c("xmrChart", "measurement", "axisLabels", "stage")) return() } @@ -70,16 +70,16 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { if (!ready) { plot <- createJaspPlot(title = gettext("Variables Charts for Individuals"), width = 700, height = 400) jaspResults[["plot"]] <- plot - plot$dependOn(c("ImRchart", "CorPlot", "variableChartIndividualsReport", "variables")) + plot$dependOn(c("xmrChart", "autocorrelationPlot", "report", "measurement")) return() } #ImR chart - if (options$ImRchart && ready) { + if (options[["xmrChart"]] && ready) { if(is.null(jaspResults[["Ichart"]])){ jaspResults[["Ichart"]] <- createJaspContainer(position = 1) - jaspResults[["Ichart"]]$dependOn(c("ImRchart", "variables", "ncol", "subgroups", "manualTicksXAxis", "manualTicksXAxisValue", "ccTitle", "ccName", "ccMisc","ccReportedBy","ccDate", "ccSubTitle", "ccChartName", "ccReport")) + jaspResults[["Ichart"]]$dependOn(c("xmrChart", "measurement", "ncol", "axisLabels", "manualTicksXAxis", "manualTicksXAxisValue", "reportTitle", "reportMeasurementName", "reportMiscellaneous","reportReportedBy","reportDate", "ccSubTitle", "ccChartName", "report")) Iplot <- jaspResults[["Ichart"]] - + ALL <- createJaspContainer(gettextf("X-mR control chart")) IMR <- .IMRchart(dataset = dataset, options = options, variable = variables, manualXaxis = subgroups, stages = stages) ALL[["Plot"]] <- IMR$p @@ -90,35 +90,36 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { } # Autocorrelation Plot - if(options$CorPlot && ready){ + if(options[["autocorrelationPlot"]] && ready){ jaspResults[["CorPlot"]] <- createJaspContainer(position = 2, title = "Autocorrelation Function") - jaspResults[["CorPlot"]]$dependOn(c("CorPlot", "variables", "nLag")) + jaspResults[["CorPlot"]]$dependOn(c("autocorrelationPlot", "measurement", "autocorrelationPlotLagsNumber")) Corplot <- jaspResults[["CorPlot"]] - Corplot[[variables]] <- .CorPlot(dataset = dataset, options = options, variable = variables, CI = options$CI, lags = options$nLag) + Corplot[[variables]] <- .CorPlot(dataset = dataset, options = options, variable = variables, + CI = options[["autocorrelationPlotCiLevel"]], lags = options[["autocorrelationPlotLagsNumber"]]) } # Report - if (options[["variableChartIndividualsReport"]] && is.null(jaspResults[["CCReport"]])) { + if (options[["report"]] && is.null(jaspResults[["CCReport"]])) { jaspResults[["CorPlot"]] <- NULL jaspResults[["Ichart"]] <- NULL jaspResults[["CCReport"]] <- createJaspContainer(gettext("Report")) - jaspResults[["CCReport"]]$dependOn(c("CCReport", "ImRchart", "variables","ncol", "manualTicksXAxis", "manualTicksXAxisValue", "subgroups", "ccTitle", "ccName", "ccMisc","ccReportedBy","ccDate", "ccSubTitle", "ccChartName")) + jaspResults[["CCReport"]]$dependOn(c("report", "xmrChart", "measurement","ncol", "manualTicksXAxis", "manualTicksXAxisValue", "axisLabels", "reportTitle", "reportMeasurementName", "reportMiscellaneous","reportReportedBy","reportDate", "ccSubTitle", "ccChartName")) jaspResults[["CCReport"]]$position <- 9 Iplot <- jaspResults[["CCReport"]] - + Iplot[["ccReport"]] <- .individualChartReport(dataset, variables, subgroups, stages, options) } # Error handling - if (options[["variableChartIndividualsReport"]] && (!options$ImRchart || length(variables) < 1)){ + if (options[["report"]] && (!options[["xmrChart"]] || length(variables) < 1)){ plot <- createJaspPlot(title = gettext("Report"), width = 700, height = 400) jaspResults[["plot"]] <- plot jaspResults[["plot"]]$setError(gettext("Please insert more measurements and check the X-mR chart.")) - plot$dependOn(c("variableChartIndividualsReport", "ImRchart", "variables")) + plot$dependOn(c("report", "xmrChart", "measurement")) return() } } @@ -144,7 +145,7 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { df1$acfstd <- sqrt(1/N * (1 + 2 * df1$lag.acf.cumsum)) df1$acfstd[1] <- 0 df1 <- dplyr::select(df1, lag, acf, acfstd) - + p <- ggplot2::ggplot(data = df1, ggplot2::aes(x = lag, y = acf)) + ggplot2::geom_col(fill = "#4373B6", width = 0.2) + jaspGraphs::geom_line(ggplot2::aes(x = lag, y = qnorm((1+CI)/2)*acfstd), color = "red") + @@ -154,25 +155,25 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { ggplot2::scale_x_continuous(name = gettext('Lag'), breaks = seq(1,max(df1$lag),2)) + jaspGraphs::geom_rangeframe() + jaspGraphs::themeJaspRaw() - + return(p) } .individualChartReport <- function(dataset, variables, subgroups, stages, options){ - - if (options[["ccTitle"]] == "") { + + if (options[["reportTitle"]] == "") { title <- gettextf("Individual charts report") }else { - title <- options[["ccTitle"]] + title <- options[["reportTitle"]] } - name <- gettextf("Name: %s", options[["ccName"]]) - date <- gettextf("Date of study: %s", options[["ccDate"]]) + name <- gettextf("Name: %s", options[["reportMeasurementName"]]) + date <- gettextf("Date of study: %s", options[["reportDate"]]) text1 <- c(name, date) - - reportedBy <- gettextf("Performed by: %s", options[["ccReportedBy"]]) - misc <- gettextf("Misc: %s", options[["ccMisc"]]) + + reportedBy <- gettextf("Performed by: %s", options[["reportReportedBy"]]) + misc <- gettextf("Misc: %s", options[["reportMiscellaneous"]]) text2 <- c(reportedBy, misc) - + plotList <- list() indexCounter <- 0 if (options[["reportMetaData"]]) { @@ -190,9 +191,9 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { } if (options[["reportAutocorrelationChart"]]) { indexCounter <- indexCounter + 1 - plotList[[indexCounter]] <- .CorPlotObject(dataset = dataset, options = options, variable = variables, CI = options$CI, lags = options$nLag) + plotList[[indexCounter]] <- .CorPlotObject(dataset = dataset, options = options, variable = variables, CI = options[["autocorrelationPlotCiLevel"]], lags = options[["autocorrelationPlotLagsNumber"]]) } - + if (indexCounter == 0) { plot <- createJaspPlot(title = title, width = 400, height = 400) plot$setError(gettext("No report components selected.")) @@ -201,13 +202,13 @@ variablesChartsIndividuals <- function(jaspResults, dataset, options) { indexCounter <- indexCounter + 1 plotList[[indexCounter]] <- ggplot2::ggplot() + ggplot2::theme_void() } - + matrixNCols <- 2 matrixNRows <- indexCounter / matrixNCols matrixPlot <- createJaspPlot(title = title, width = 1200, height = 400 * matrixNRows) plotMat <- matrix(plotList, matrixNRows, matrixNCols, byrow = TRUE) p <- jaspGraphs::ggMatrixPlot(plotMat) matrixPlot$plotObject <- p - + return(matrixPlot) -} \ No newline at end of file +} diff --git a/inst/Upgrades.qml b/inst/Upgrades.qml index 9424e9d3..a2a7e860 100644 --- a/inst/Upgrades.qml +++ b/inst/Upgrades.qml @@ -35,6 +35,16 @@ Upgrades ChangeRename { from: "ncol"; to: "movingRangeLength" } } + Upgrade + { + functionName: "variablesChartsIndividuals" + fromVersion: "0.17.3" + toVersion: "0.18.0" + + ChangeRename { from: "CCReport"; to: "variableChartIndividualsReport" } + } + + // option renaming for syntax // Type 1 Gauge Study @@ -434,9 +444,10 @@ Upgrades // main analysis ChangeRename {from: "variables"; to: "measurement"} - ChangeRename {from: "subgroups"; to: "subgroup"} + ChangeRename {from: "subgroups"; to: "axisLabels"} + ChangeRename {from: "split"; to: "stage"} ChangeRename {from: "ImRchart"; to: "xmrChart"} - ChangeRename {from: "ncol"; to: "xmrChartMovingRangeLength"} + ChangeRename {from: "movingRangeLength"; to: "xmrChartMovingRangeLength"} ChangeRename {from: "manualTicks"; to: "manualTicksXAxis"} ChangeRename {from: "nTicks"; to: "manualTicksXAxisValue"} ChangeRename {from: "CorPlot"; to: "autocorrelationPlot"} @@ -445,14 +456,12 @@ Upgrades // report - ChangeRename {from: "CCReport"; to: "report"} + ChangeRename {from: "variableChartIndividualsReport"; to: "report"} ChangeRename {from: "ccTitle"; to: "reportTitle"} ChangeRename {from: "ccName"; to: "reportMeasurementName"} ChangeRename {from: "ccDate"; to: "reportDate"} ChangeRename {from: "ccReportedBy"; to: "reportReportedBy"} ChangeRename {from: "ccMisc"; to: "reportMiscellaneous"} - ChangeRename {from: "ccSubTitle"; to: "reportSubtitle"} - ChangeRename {from: "ccChartName"; to: "reportChartName"} } // Control Charts for Attributes @@ -630,6 +639,7 @@ Upgrades ChangeRename {from: "csConfidenceIntervalPercent"; to: "processCapabilityTableCiLevel"} ChangeRename {from: "xbarR"; to: "xBarAndRChart"} ChangeRename {from: "IMR"; to: "xmrChart"} + ChangeRename {from: "movingRangeLength"; to: "xmrChartMovingRangeLength"} ChangeRename {from: "displayDensity"; to: "histogramDensityLine"} ChangeRename {from: "pcNumberOfBins"; to: "histogramBinNumber"} ChangeRename {from: "addGridlines"; to: "probabilityPlotGridLines"} diff --git a/inst/qml/processCapabilityStudies.qml b/inst/qml/processCapabilityStudies.qml index 6a000ea0..7d54f94f 100644 --- a/inst/qml/processCapabilityStudies.qml +++ b/inst/qml/processCapabilityStudies.qml @@ -280,7 +280,7 @@ Form DoubleField { - name: "movingRangeLength" + name: "xmrChartMovingRangeLength" label: qsTr("Moving range length") defaultValue: 2 min: 2 diff --git a/inst/qml/variablesChartsIndividuals.qml b/inst/qml/variablesChartsIndividuals.qml index 3cfbc089..800deb41 100644 --- a/inst/qml/variablesChartsIndividuals.qml +++ b/inst/qml/variablesChartsIndividuals.qml @@ -18,15 +18,15 @@ Form AssignedVariablesList { - name: "variables" - title: qsTr("Variables") + name: "measurement" + title: qsTr("Measurement") singleVariable: true allowedColumns: ["scale"] } AssignedVariablesList { - name: "subgroups" + name: "axisLabels" title: qsTr("Axis labels") singleVariable: true allowedColumns: ["nominal", "nominalText", "ordinal"] @@ -34,8 +34,8 @@ Form AssignedVariablesList { - name: "split" - title: qsTr("Stages") + name: "stage" + title: qsTr("Stage") singleVariable: true allowedColumns: ["nominal", "nominalText", "ordinal"] } @@ -47,13 +47,13 @@ Form CheckBox { - name: "ImRchart" + name: "xmrChart" label: qsTr("X-mR chart") checked: true DoubleField { - name: "movingRangeLength" + name: "xmrChartMovingRangeLength" label: qsTr("Moving range length") defaultValue: 2 min: 2 @@ -75,13 +75,13 @@ Form CheckBox { - name: "CorPlot" + name: "autocorrelationPlot" label: qsTr("Autocorrelation") checked: false DoubleField { - name: "nLag" + name: "autocorrelationPlotLagsNumber" label: qsTr("Number of lags") defaultValue: 25 min: 1 @@ -89,10 +89,10 @@ Form DoubleField { - name: "CI" + name: "autocorrelationPlotCiLevel" label: qsTr("Confidence interval size") defaultValue: 0.95 - min: 0.0001 + min: 0.0001 } } } @@ -103,7 +103,7 @@ Form CheckBox { - name: "variableChartIndividualsReport" + name: "report" label: qsTr("Show report") id: variableChartIndividualsReport columns: 2 @@ -116,45 +116,45 @@ Form TextField { - id: ccTitle + id: reportTitle label: qsTr("Title") - name: "ccTitle" + name: "reportTitle" placeholderText: qsTr("Measurement") fieldWidth: 100 } TextField { - id: ccName + id: reportMeasurementName label: qsTr("Name") - name: "ccName" + name: "reportMeasurementName" placeholderText: qsTr("Name") fieldWidth: 100 } TextField { - id: ccDate + id: reportDate label: qsTr("Date") - name: "ccDate" + name: "reportDate" placeholderText: qsTr("Date") fieldWidth: 100 } TextField { - id: ccReportedBy + id: reportReportedBy label: qsTr("Reported by") - name: "ccReportedBy" + name: "reportReportedBy" placeholderText: qsTr("Name") fieldWidth: 100 } TextField { - id: ccMisc + id: reportMiscellaneous label: qsTr("Misc") - name: "ccMisc" + name: "reportMiscellaneous" placeholderText: qsTr("Miscellaneous") fieldWidth: 100 } diff --git a/tests/testthat/test-variablesChartsIndividuals.R b/tests/testthat/test-variablesChartsIndividuals.R index 6b54686b..ebea899e 100644 --- a/tests/testthat/test-variablesChartsIndividuals.R +++ b/tests/testthat/test-variablesChartsIndividuals.R @@ -2,10 +2,10 @@ context("[Quality Control] Variables Charts for Individuals") # basic test for IMR chart & table (verified with Minitab) and autocorrelation plot options <- analysisOptions("variablesChartsIndividuals") -options$variables <- "Yield" -options$subgroups <- "Month" -options$CorPlot <- TRUE -options$movingRangeLength <- 2 +options$measurement <- "Yield" +options$axisLabels <- "Month" +options$autocorrelationPlot <- TRUE +options$xmrChartMovingRangeLength <- 2 set.seed(1) results <- runAnalysis("variablesChartsIndividuals", "IndividualChartStages.csv", options) @@ -37,8 +37,8 @@ test_that("Test results for range chart table results match", { }) # test for different moving range lengths (verified with Minitab) -options$CorPlot <- FALSE -options$movingRangeLength <- 5 +options$autocorrelationPlot <- FALSE +options$xmrChartMovingRangeLength <- 5 results <- runAnalysis("variablesChartsIndividuals", "IndividualChartStages.csv", options) @@ -64,7 +64,7 @@ test_that("Test results for range chart table results match", { }) # test for more extreme moving range length (verified with Minitab) -options$movingRangeLength <- 30 +options$xmrChartMovingRangeLength <- 30 results <- runAnalysis("variablesChartsIndividuals", "IndividualChartStages.csv", options) test_that("titleless-plot-3 matches", { plotName <- results[["results"]][["Ichart"]][["collection"]][["Ichart_Yield"]][["collection"]][["Ichart_Yield_Plot"]][["data"]] @@ -82,8 +82,8 @@ test_that("Test results for individuals chart table results match", { }) # test analysis of stages plot (verified with Minitab) -options$split <- "Stage" -options$movingRangeLength <- 2 +options$stage <- "Stage" +options$xmrChartMovingRangeLength <- 2 results <- runAnalysis("variablesChartsIndividuals", "IndividualChartStages.csv", options)