R/minimize.R

Defines functions `eqmcc` `minimizeLoop` `minimize`

# Copyright (c) 2016 - 2020, Adrian Dusa
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, in whole or in part, are permitted provided that the
# following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * The names of its contributors may NOT be used to endorse or promote products
#       derived from this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL ADRIAN DUSA BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

`minimize` <-
function(input, include = "", dir.exp = NULL, details = FALSE, all.sol = FALSE,
        row.dom = FALSE, min.pin = FALSE, max.comb = 0, first.min = FALSE,
        method = "CCubes", ...) {
    metacall <- match.call()
    dots <- substitute(list(...))
    if (is.element("data", names(dots))) {
        input <- eval.parent(dots$data)
        dots$data <- NULL
    }
    enter <- if (is.element("enter", names(dots))) "" else "\n" 
    if (missing(input)) {
        cat(enter)
        stop(simpleError(paste0("The input (a truth table or a dataset) is missing.", enter, enter)))
    }
    else {
        if (is.matrix(input)) {
            if (is.null(colnames(input))) {
                cat(enter)
                stop(simpleError(paste0("The data should have column names.", enter, enter)))
            }
            if (any(duplicated(rownames(input)))) {
                rownames(input) <- seq(nrow(input))
            }
            input <- as.data.frame(input)
            for (i in seq(ncol(input))) {
                if (admisc::possibleNumeric(input[, i])) {
                    input[, i] <- admisc::asNumeric(input[, i])
                }
            }
        }
        if(!(is.data.frame(input) | methods::is(input, "QCA_tt"))) {
            cat(enter)
            stop(simpleError(paste0("The input should be a truth table or a dataset.", enter, enter)))
        }
    }
    ttinput <- methods::is(input, "QCA_tt")
    print.truth.table <- details & !ttinput
    if (ttinput) {
        nms <- colnames(input$recoded.data)[seq(length(input$noflevels))]
    }
    else {
        nms <- colnames(input)
    }
    if (length(dots) > 1) {
        for (i in seq(2, length(dots))) {
            dots[[i]] <- admisc::recreate(dots[[i]], nms)
        }
    }
    dots <- eval(dots)
    back.args <- c("outcome", "conditions", "n.cut", "incl.cut", "complete", "show.cases", sort.by = "", "use.letters", "inf.test",
                   "rowdom", "direxp", "neg.out", "data", "relation", "explain", "omit", "exclude")
    check.args <- pmatch(names(dots), back.args)
    names(dots)[!is.na(check.args)] <- back.args[check.args[!is.na(check.args)]]
    explain     <- if (is.element("explain",     names(dots))) dots$explain      else "1"
    outcome     <- if (is.element("outcome",     names(dots))) dots$outcome      else ""
    conditions  <- if (is.element("conditions",  names(dots))) dots$conditions   else ""
    incl.cut    <- if (is.element("incl.cut",    names(dots))) dots$incl.cut     else 1
    n.cut       <- if (is.element("n.cut",       names(dots))) dots$n.cut        else 1
    complete    <- if (is.element("complete",    names(dots))) dots$complete     else FALSE
    show.cases  <- if (is.element("show.cases",  names(dots))) dots$show.cases   else FALSE
    dcc         <- if (is.element("dcc",         names(dots))) dots$dcc          else FALSE
    sort.by     <- if (is.element("sort.by",     names(dots))) dots$sort.by      else ""
    use.letters <- if (is.element("use.letters", names(dots))) dots$use.letters  else FALSE
    inf.test    <- if (is.element("inf.test",    names(dots))) dots$inf.test     else ""
    relation    <- if (is.element("relation",    names(dots))) dots$relation     else "sufficiency"
    neg.out     <- if (is.element("neg.out",     names(dots))) dots$neg.out      else FALSE
    pi.cons     <- if (is.element("pi.cons",     names(dots))) dots$pi.cons      else 0
    pi.depth    <- if (is.element("pi.depth",    names(dots))) dots$pi.depth     else 0
    sol.cons    <- if (is.element("sol.cons",    names(dots))) dots$sol.cons     else 0
    sol.cov     <- if (is.element("sol.cov",     names(dots))) dots$sol.cov      else 1
    sol.depth   <- if (is.element("sol.depth",   names(dots))) dots$sol.depth    else 0
    exclude     <- if (is.element("exclude",     names(dots))) dots$exclude      else NULL
    keep.trying <- if (is.element("keep.trying", names(dots))) dots$keep.trying  else FALSE
    if (is.null(exclude)) {
        if (is.element("omit", names(dots))) {
            exclude <- dots$omit
        }
    }
    if (is.null(include)) {
        cat(enter)
        stop(simpleError(paste0("The \"include\" argument cannot be NULL.", enter, enter)))
    }
    dir.exp <- admisc::recreate(substitute(dir.exp))
    row.dom     <- if (is.element("rowdom",      names(dots))) dots$rowdom       else row.dom
    dir.exp     <- if (is.element("direxp",      names(dots))) dots$direxp       else dir.exp
    if (identical(dir.exp, character(0))) {
        dir.exp <- NULL
    }
    else if (!is.null(dir.exp)) {
        if (length(dir.exp) == 1) {
            if (grepl(":", dir.exp)) {
                des <- unlist(strsplit(dir.exp, split = ":"))
                if (!all(is.element(des, nms))) {
                    cat(enter)
                    stop(simpleError(paste0("Inexisting condition(s) in the sequence of directional expectations.", enter, enter)))
                }
                dir.exp <- nms[seq(which(nms == des[1]), which(nms == des[2]))]
            }
            else {
                dir.exp <- admisc::splitstr(dir.exp)
            }
        }
    }
    if (identical(include, "")) {
        if (!is.null(dir.exp)) {
            cat(enter)
            stop(simpleError(paste0("Directional expectations cannot be specified without including the remainders.", enter, enter)))
        }
    }
    if (is.character(explain) & !identical(explain, "1")) {
        explain <- admisc::splitstr(explain)
    }
    if (is.character(include) & !identical(include, "")) {
        include <- admisc::splitstr(include)
    }
    if (is.character(outcome) & !identical(outcome, "")) {
        outcome <- admisc::splitstr(outcome)
    }
    if (ttinput) { 
        tt <- input
        curly <- grepl("\\{", tt$options$outcome)
        if (is.null(tt$options$exclude) & !is.null(exclude)) {
            callist <- as.list(tt$call)
            dataname <- callist$data
            callist$data <- tt$initial.data
            callist$exclude <- exclude
            tt <- do.call("truthTable", callist[-1])
            callist$data <- dataname
            tt$call <- as.call(callist)
        }
        recdata <- tt$recoded.data
        conditions <- colnames(recdata)[seq(length(tt$noflevels))]
        outcome <- colnames(recdata)[ncol(recdata)]
        indata <- tt$initial.data[, match(colnames(recdata), colnames(tt$initial.data)), drop = FALSE]
    }
    else {
        if (identical(outcome, "")) {
            cat(enter)
            stop(simpleError(paste0("Consider creating a truth table first, or formally specify the argument \"outcome\".", enter, enter)))
        }
        if (any(c(pi.cons, sol.cons) > 0) & incl.cut[1] == 1) {
            incl.cut[1] <- min(c(pi.cons, sol.cons))
        }
        if (length(outcome) > 1) {
            return(do.call("minimizeLoop", as.list(metacall)[-1], envir = parent.frame()))
        }
        outcome.copy <- outcome
        indata <- input 
        curly <- grepl("\\{", outcome)
        testoutcome <- ifelse(curly,
                            admisc::curlyBrackets(admisc::notilde(outcome), outside = TRUE),
                            admisc::squareBrackets(admisc::notilde(outcome), outside = TRUE))
        if (!is.element(testoutcome, colnames(input))) {
            cat(enter)
            stop(simpleError(paste0("Outcome not found in the data.", enter, enter)))
        }
        outcome.name <- testoutcome
        if (identical(conditions, "")) {
            conditions <- names(input)[-which(names(input) == outcome.name)]
        }
        else {
            conditions <- admisc::splitstr(conditions)
        }
        verify.data(input, outcome.name, conditions)
        if (length(conditions) == 1) {
            if (grepl(":", conditions)) {
                nms <- colnames(data)
                cs <- unlist(strsplit(conditions, split = ":"))
                conditions <- nms[seq(which(nms == cs[1]), which(nms == cs[2]))]
            }
        }
        input <- input[, c(conditions, outcome.name)]
        verify.minimize(input, outcome.name, conditions, explain, include, use.letters)
        if (!is.element("incl.cut", names(dots))) {
            dots$incl.cut <- incl.cut
        }
        tt <- do.call("truthTable", c(list(data = input), dots))
        tt$initial.data <- indata
        indata <- input 
        recdata <- tt$recoded.data
        outcome <- outcome.name
        names(indata) <- c(conditions, outcome)
    }
    use.letters <- tt$options$use.letters
    show.cases <- show.cases | tt$options$show.cases 
    neg.out <- tt$options$neg.out
    output <- list()
    output$tt <- tt
    output$options$print.truth.table <- print.truth.table
    rowsNotMissing <- which(tt$tt$OUT != "?")
    if (any(tt$tt$OUT == "?")) {
        missings <- which(tt$tt$OUT == "?")
        tt$tt <- tt$tt[-missings, , drop = FALSE]
    }
    ttrownms <- admisc::asNumeric(rownames(tt$tt))
    noflevels <- tt$noflevels
    mbase <- as.integer(rev(c(1, cumprod(rev(noflevels))))[-1])
    mbaseplus <- rev(c(1, cumprod(rev(noflevels + 1))))[-1]
    alreadyletters <- sum(nchar(colnames(recdata)[-ncol(recdata)])) == ncol(recdata) - 1
    tt$tt[seq(length(conditions))] <- as.data.frame(lapply(tt$tt[seq(length(conditions))], function(x) {
        x[is.element(x, c("-", "dc"))] <- -1
        return(admisc::asNumeric(x))
    }))
    pos.incl <- unique(c(explain, include)) 
    subset.tt <- ttrownms[is.element(tt$tt[, "OUT"], explain)]
    subset.pos <- is.element(tt$tt[, "OUT"], pos.incl)
    pos.matrix <- as.matrix(tt$tt[subset.pos, seq(length(noflevels))])
    rownames(pos.matrix) <- drop(pos.matrix %*% mbase) + 1
    pos.matrix <- pos.matrix + 1
    neg.matrix <- as.matrix(tt$tt[!is.element(tt$tt[, "OUT"], pos.incl), seq(length(noflevels))])
    neg.matrix <- matrix(as.numeric(neg.matrix), ncol = length(noflevels)) + 1
    rownames(neg.matrix) <- drop((neg.matrix - 1) %*% mbase) + 1
    if (sum(subset.pos) == 0) {
        cat(enter)
        stop(simpleError(paste0("None of the values in OUT is explained. Please check the truth table.", enter, enter)))
    }
    inputt <- as.matrix(tt$tt[is.element(ttrownms, subset.tt), seq(length(noflevels)), drop = FALSE])
    rownames(inputt) <- drop(inputt %*% mbase) + 1
    inputt <- inputt + 1
    inputcases <- tt$cases[is.element(tt$indexes, subset.tt)]
    nofcases1 <- sum(tt$tt$n[tt$tt$OUT == 1])
    nofcases0 <- sum(tt$tt$n[tt$tt$OUT == 0])
    nofcasesC <- sum(tt$tt$n[tt$tt$OUT == "C"])
    excl.matrix <- matrix(nrow = 0, ncol = length(conditions))
    output$negatives <- sort(drop((neg.matrix - 1) %*% mbase) + 1)
    rownms <- rownames(inputt)
    if (nrow(pos.matrix) == 0) {
        cat(enter)
        stop(simpleError(paste0("Nothing to explain. Please check the truth table.", enter, enter)))
    }
    incl.rem <- is.element("?", include)
    if (nrow(neg.matrix) == 0 & incl.rem & !is.element("causalChain", names(dots))) { 
        cat(enter)
        stop(simpleError(paste0("All truth table configurations are used, all conditions are minimized.\n",
                   "       Please check the truth table.", enter, enter)))
    }
    expressions <- pos.matrix
    recdata[, conditions] <- as.data.frame(lapply(recdata[, conditions, drop = FALSE], function(x) {
        x[is.element(x, c("-", "?", "dc"))] <- -1
        return(as.numeric(x))
    }))
    mv <- any(recdata[, seq(ncol(recdata) - 1)] > 1)
    collapse <- "*"
    changed <- FALSE
    if (use.letters & !alreadyletters) {
        colnms <- LETTERS[seq(ncol(inputt))]
        changed <- TRUE
    }
    else {
        colnms <- colnames(recdata[, seq(ncol(inputt)), drop = FALSE])
    }
    setColnames(expressions, colnms)
    setColnames(inputt, colnms)
    setColnames(pos.matrix, colnms)
    setColnames(neg.matrix, colnms)
    rownames(neg.matrix) <- (neg.matrix - 1) %*% mbase + 1
    output$initials <- admisc::writePrimeimp(inputt, mv = mv, collapse = collapse)
    if (any(c(pi.cons, sol.cons) > 0)) {
        incl.rem <- TRUE
        method <- "CCubes"
    }
    expressions <- .Call("C_QMC", expressions, noflevels, PACKAGE = "QCA")
    if (is.element("simplify", names(dots))) {
        expressions <- admisc::sortExpressions(expressions)
    }
    callist <- list(expressions=expressions, mv=mv, collapse=collapse, inputt=inputt, row.dom=row.dom,
                    initial=rownms, all.sol=all.sol, indata=indata, curly=curly)
    callist <- c(callist, dots)
    if (!incl.rem || (!is.null(dir.exp) & !identical(include, ""))) {
        c.sol <- p.sol <- do.call("getSolution", callist)
    }
    if (incl.rem) {
        pos.matrix <- inputt
        if (method == "QMC") {
            expressions <- .Call("C_QMC", createMatrix(noflevels)[-output$negatives, , drop = FALSE] + 1, noflevels, PACKAGE = "QCA")
            setColnames(expressions, colnames(inputt))
        }
        else if (method == "eQMC") {
            if (nrow(neg.matrix) > 0) {
                expressions <- sort.int(setdiff(findSupersets(pos.matrix, noflevels + 1), findSupersets(neg.matrix, noflevels + 1)))
            }
            else {
                expressions <- sort.int(findSupersets(pos.matrix, noflevels + 1))
            }
            expressions <- .Call("C_removeRedundants", expressions, noflevels, mbaseplus, PACKAGE = "QCA")
            expressions <- admisc::sortExpressions(getRow(expressions, noflevels + 1))
            setColnames(expressions, colnames(inputt))
        }
        else { 
            extended.data <- as.matrix(tt$recoded.data)
            if (nrow(excl.matrix) > 0) {
                extended.data <- rbind(extended.data, cbind(excl.matrix, 0))
            }
            if (sol.cons > 0 & all.sol & sol.depth == 0) {
                sol.depth <- 7
            }
            expressions <- .Call("C_Cubes", list(
                            tt = cbind(rbind(pos.matrix, neg.matrix) - 1, rep(c(1, 0), c(nrow(pos.matrix), nrow(neg.matrix)))),
                            data = extended.data,
                            all.sol = all.sol,
                            row.dom = row.dom,
                            min.pin = min.pin,
                            pi.cons = pi.cons,
                            depth = as.integer(c(pi.depth, sol.depth)),
                            sol.cons = sol.cons,
                            sol.cov = sol.cov,
                            fs = tt$fs,
                            max.comb = max.comb,
                            first.min = first.min,
                            keep.trying = keep.trying),
                            PACKAGE = "QCA")
        }
        callist$expressions <- expressions
        p.sol <- do.call("getSolution", callist)
    }
    output$PIchart <- p.sol$mtrx
    class(output$PIchart) <- c("matrix", "QCA_pic")
    attr(output$PIchart, "PI") <- p.sol$expressions
    output$primes    <- p.sol$reduced$expressions
    output$solution  <- p.sol$solution.list[[1]]
    output$essential <- p.sol$solution.list[[2]]
    output$options$explain     <- explain
    output$options$neg.out     <- neg.out
    output$options$details     <- details
    output$options$sol.cons    <- sol.cons
    output$options$sol.cov     <- sol.cov
    output$options$relation    <- relation
    output$options$show.cases  <- show.cases
    output$options$use.letters <- use.letters
    output$options$collapse    <- collapse
    output$options$curly       <- curly
    expr.cases <- rep(NA, nrow(p.sol$reduced$expressions))
    tt.rows <- admisc::writePrimeimp(inputt, mv = mv, collapse = collapse)
    if (any(grepl("[*]", rownames(p.sol$reduced$expressions)))) {
        if (use.letters) {
            mtrxlines <- makeChart(primes = rownames(p.sol$reduced$expressions), snames = LETTERS[seq(length(conditions))], configs = tt.rows, mv = mv, noflevels = noflevels)
        }
        else {
            mtrxlines <- makeChart(primes = rownames(p.sol$reduced$expressions), snames = conditions, configs = tt.rows, mv = mv, noflevels = noflevels)
        }
    }
    else {
        if (use.letters) {
            mtrxlines <- makeChart(primes = rownames(p.sol$reduced$expressions), configs = tt.rows, snames = LETTERS[seq(length(conditions))], mv = mv, noflevels = noflevels)
        }
        else {
            mtrxlines <- makeChart(primes = rownames(p.sol$reduced$expressions), configs = tt.rows, snames = conditions, mv = mv, noflevels = noflevels)
        }
    }
    colnames(mtrxlines) <- colnames(p.sol$reduced$mtrx) <- rownms
    for (l in seq(length(expr.cases))) {
        expr.cases[l] <- paste(inputcases[mtrxlines[l, ]], collapse="; ")
    }
    output$inputcases <- inputcases
    conds <- conditions
    if (all(is.element(colnames(p.sol$reduced$expressions), conditions))) {
        conds <- colnames(p.sol$reduced$expressions)
    }
    else {
        if (all(is.element(colnames(p.sol$reduced$expressions), LETTERS))) {
            conds <- conditions[match(colnames(p.sol$reduced$expressions), LETTERS)]
        }
    }
    poflist <- list(setms = paste(rownames(p.sol$reduced$expressions), collapse = "+"),
                    outcome = tt$options$outcome, data = indata, neg.out = neg.out,
                    use.letters = tt$options$use.letters, show.cases = TRUE, cases = expr.cases,
                    conditions = conds, relation = "sufficiency", minimize = TRUE)
    if (length(output$solution) > 1) {
        poflist$solution.list <- output$solution
        poflist$essential <- output$essential
    }
    if (!is.element("simplify", names(dots))) {
        listIC <- do.call("pof", poflist)
        listIC$options$show.cases <- show.cases
        output$pims <- listIC$pims
        attr(output$pims, "conditions") <- conditions
        output$IC <- listIC
    }
    output$numbers <- c(OUT1 = nofcases1, OUT0 = nofcases0, OUTC = nofcasesC, Total = nofcases1 + nofcases0 + nofcasesC)
    mtrx <- p.sol$mtrx[p.sol$all.PIs, , drop = FALSE]
    SA <- TRUE
    if (is.element("SA", names(dots))) {
        SA <- dots$SA
    }
    if (SA & 3^length(noflevels) < 2^31) {
        conds <- conditions
        if (tt$options$use.letters) {
            conds <- LETTERS[seq(length(conditions))]
        }
        mbaseexpr <- rev(c(1, cumprod(rev(noflevels[is.element(conds, colnames(p.sol$reduced$expressions))] + 1))))[-1]
        output$SA <- lapply(p.sol$solution.list[[1]], function(x) {
            p.expressions <- p.sol$reduced$expressions[x, , drop = FALSE]
            temp <- apply(p.expressions, 1, function(pr) {
                indices <- rev(which(pr == 0))
                tempr <- NULL
                for (k in indices) {
                    if (is.null(tempr)) {
                        tempr <- drop(mbaseexpr %*% pr) + sum(mbaseexpr[pr == 0])
                        temp2 <- tempr
                    }
                    for (lev in seq(noflevels[k] - 1)) {
                        temp2 <- c(temp2, tempr + mbaseexpr[k]*lev)
                    }
                    tempr <- temp2
                }
                return(tempr)
            })
            if (all(is.null(temp))) {
                SAx <- matrix(nrow = 0, ncol = ncol(inputt))
            }
            else {
                temp <- sort(unique(as.vector(unlist(temp))))
                temp <- temp[!is.element(temp, drop(inputt %*% mbaseplus))]
                if (length(temp) == 0) {
                    SAx <- matrix(nrow = 0, ncol = ncol(inputt))
                }
                else {
                    SAx <- getRow(temp + 1, noflevels + 1) - 1L
                    rownames(SAx) <- drop(SAx %*% mbase) + 1
                }
            }
            colnames(SAx) <- colnames(inputt)
            return(SAx)
        })
        prettyNums <- formatC(seq(length(p.sol$solution.list[[1]])), digits = nchar(length(p.sol$solution.list[[1]])) - 1, flag = 0)
        if (!is.null(dir.exp) & !identical(include, "")) {
            if (!identical(c.sol$solution.list, NA)) {
            dir.exp <- verify.dir.exp(recdata, outcome, conditions, noflevels, dir.exp, enter)
            isoliscsol <- identical(dir.exp, matrix(0L, ncol = length(conditions)))
            if (all(unlist(lapply(output$SA, is.null))) | isoliscsol) {
                ECmat <- as.data.frame(matrix(ncol = length(conditions), nrow = 0))
                colnames(ECmat) <- colnames(inputt)
            }
            else {
                result <- .Call("C_getEC", dir.exp,
                    c.sol$expressions, c.sol$sol.matrix,
                    p.sol$expressions, p.sol$sol.matrix,
                    output$SA, as.integer(noflevels),
                    PACKAGE = "QCA")
                EClist <- result[[1]]
                isols <- result[[2]]
                intsel <- result[[3]]
            }
            tt.rows <- admisc::writePrimeimp(inputt, mv = mv, collapse = collapse)
            i.sol <- vector("list", ncol(c.sol$sol.matrix)*ncol(p.sol$sol.matrix))
            index <- 1
            for (c.s in seq(ncol(c.sol$sol.matrix))) {
                for (p.s in seq(ncol(p.sol$sol.matrix))) {
                    names(i.sol)[index] <- paste("C", c.s, "P", p.s, sep = "")
                    if (all(unlist(lapply(output$SA, is.null))) | isoliscsol) {
                        i.sol[[index]]$EC <- ECmat
                        i.sol[[index]]$DC <- ECmat
                        i.sol.index <- c.sol
                        i.sol.index$solution.list[[1]] <- c.sol$solution.list[[1]][[c.s]]
                    }
                    else {
                        i.sol[[index]]$EC <- EClist[[index]]
                        i.sol[[index]]$DC <- output$SA[[p.s]][setdiff(rownames(output$SA[[p.s]]), rownames(EClist[[index]])), , drop = FALSE]
                        pos.matrix.i.sol <- unique(as.matrix(rbind(pos.matrix, EClist[[index]] + 1L)))
                        expressions <- .Call("C_QMC", pos.matrix.i.sol, noflevels, PACKAGE = "QCA")
                        callist$expressions <- expressions
                        i.sol.index <- do.call("getSolution", callist)
                        i.sol.index$expressions <- i.sol.index$expressions[rowSums(i.sol.index$mtrx) > 0, , drop = FALSE]
                    }
                    i.sol[[index]]$solution       <- i.sol.index$solution.list[[1]]
                    i.sol[[index]]$essential      <- i.sol.index$solution.list[[2]]
                    i.sol[[index]]$primes         <- i.sol.index$reduced$expressions
                    i.sol[[index]]$PIchart        <- i.sol.index$mtrx
                    class(i.sol[[index]]$PIchart) <- c("matrix", "QCA_pic")
                    i.sol[[index]]$c.sol          <- c.sol$solution.list[[1]][[c.s]]
                    i.sol[[index]]$p.sol          <- p.sol$solution.list[[1]][[p.s]]
                    expr.cases <- rep(NA, nrow(i.sol.index$reduced$expressions))
                    if (use.letters) {
                        mtrxlines <- makeChart(primes = rownames(i.sol.index$reduced$expressions), configs = tt.rows, snames = LETTERS[seq(length(conditions))], mv = mv, noflevels = noflevels)
                    }
                    else {
                        mtrxlines <- makeChart(primes = rownames(i.sol.index$reduced$expressions), configs = tt.rows, snames = conditions, mv = mv, noflevels = noflevels)
                    }
                    for (l in seq(length(expr.cases))) {
                        expr.cases[l] <- paste(inputcases[which(mtrxlines[l, ])], collapse="; ")
                    }
                    poflist <- list(setms = paste(rownames(i.sol.index$reduced$expressions), collapse = "+"),
                                    outcome = tt$options$outcome, data = indata, neg.out = neg.out,
                                    use.letters = tt$options$use.letters, show.cases = TRUE, cases = expr.cases,
                                    conditions = conditions, relation = "sufficiency", minimize = TRUE)
                    if (length(i.sol.index$solution.list[[1]]) > 1) {
                        poflist$solution.list <- i.sol.index$solution.list[[1]]
                        poflist$essential <- i.sol.index$solution.list[[2]]
                    }
                    i.sol[[index]]$IC <- do.call("pof", poflist)
                    i.sol[[index]]$IC$options$show.cases <- show.cases
                    i.sol[[index]]$pims <- i.sol[[index]]$IC$pims
                    attr(i.sol[[index]]$pims, "conditions") <- conditions
                    i.sol[[index]]$IC$pims <- NULL
                    index <- index + 1
                }
            }
            output$i.sol <- i.sol
        }}
        names(output$SA) <- paste("M", prettyNums, sep = "")
        output$SA <- lapply(output$SA, as.data.frame)
    }
    if (any(names(output) == "i.sol")) {
        for (i in seq(length(output$i.sol))) {
            output$i.sol[[i]]$EC <- as.data.frame(output$i.sol[[i]]$EC)
        }
    }
    if (!methods::is(input, "QCA_tt")) {
        output$tt$options$outcome <- outcome.copy
    }
    output$complex <- p.sol$complex
    output$call <- metacall
    if (is.element("via.web", names(dots))) {
        output$via.web <- TRUE
    }
    if (mv & !grepl(mvregexp, output$tt$options$outcome)) {
        output$tt$options$outcome <- paste(output$tt$options$outcome, "[1]", sep = "")
    }
    return(structure(output, class = "QCA_min"))
}
`minimizeLoop` <-
function(...) {
    allargs <- list(...)
    verify.mqca(allargs)
    outcome <- admisc::splitstr(allargs$outcome)
    minimize.list <- lapply(outcome, function(x) {
        allargs[["outcome"]] <- x
        return(do.call("minimize", allargs))
    })
    names(minimize.list) <- outcome
    return(structure(minimize.list, class = "QCA_loopmin"))
}
`eqmcc` <- function(...) {
    .Deprecated(msg = "Function eqmcc() is deprecated, and has been renamed to minimize()\n")
    minimize(...)
}

Try the QCA package in your browser

Any scripts or data that you put into this service are public.

QCA documentation built on Nov. 29, 2020, 3:01 p.m.