qca_solutions: Consolidates Conservative, Intermediate, and Parsimonious solutions into a unified data frame.

GitHub Repository: https://github.com/marisguia/qca_solutions

Breno A. H. Marisguia - Universidade Federal de Minas Gerais - marisguiabreno@gmail.com<

Introduction

The qca_solutions function is designed to streamline the process of consolidating Conservative, Intermediate, and Parsimonious solutions from the QCA Package (Dușa, 2019) into a unified dataframe. This function allows you to easily handle multiple types of solutions, apply filtering based on consistency thresholds, round numeric values, and save results to an Excel file.

Full documentation, example usage, and source code on GitHub: https://github.com/marisguia/qca_solutions

Function Usage

qca_solutions(c = NULL, i = NULL, icp = NULL, p = NULL, verbose = TRUE, save = NULL, round = NULL, incl.cut = NULL)

Arguments

  • c
    A conservative solution object of class "QCA_min".

  • i
    An intermediate solution object of class "QCA_min".

  • icp
    A character vector specifying which CnPn (configurations of necessary and possible necessary conditions) to include for intermediate solutions.

  • p
    A parsimonious solution object of class "QCA_min".

  • verbose
    Logical. If TRUE (default), progress messages are displayed.

  • save
    A character string specifying the file path to save the results. If NULL (default), no file is saved.

  • round
    An integer specifying the number of decimal places to round numeric columns (e.g., 2 for two decimal places). If NULL, no rounding is applied.

  • incl.cut
    A numeric value specifying the threshold for Consistency_PI. Prime implicants with Consistency_PI below this value are excluded. If NULL, no filtering is applied.

Example

Truth Table. Lipset dataset (1959).

library(QCA)

tt <- truthTable(LF, outcome = SURV, incl.cut = .5) # Low incl.cut to generate multiple models for this example
Logical reminders suppressed due to extension.
DEV URB LIT IND STB OUT n incl PRI cases
1 1 1 1 1 1 4 0.90 0.89 BE,CZ,NL,UK
1 0 1 0 1 1 2 0.80 0.72 FI,IE
1 0 1 1 1 1 2 0.71 0.63 FR,SE
0 0 1 0 1 1 1 0.53 0.23 EE
0 0 1 0 0 1 2 0.52 0.11 HU,PL
1 1 1 1 0 0 1 0.45 0.05 DE
1 0 1 1 0 0 1 0.38 0.04 AU
0 0 0 0 1 0 2 0.28 0.00 IT,RO
0 0 0 0 0 0 3 0.22 0.00 GR,PT,ES
# Solutions
c_solution <- minimize(tt) # Conservative

i_solution <- minimize(tt, include = "?", dir.exp = "1, 1, 1, 1, 1") # Intermediate

p_solution <- minimize(tt, include = "?") # Parsimonious

Conservative solution

qca_c_solution <- qca_solutions(c = c_solution, round = 2)

print(qca_c_solution)
Solution Model Intermediate_CnPn Prime_Implicants Consistency_PI PRI_PI Raw_Coverage_PI Unique_Coverage_PI Solution_Consistency Solution_PRI Solution_Coverage Cases
Conservative 1
~DEV*~URB*LIT*~IND 0.46 0.15 0.22 0.08 0.73 0.68 0.90 EE, HU, PL
Conservative 1
DEV*~URB*LIT*STB 0.81 0.76 0.43 0.11 0.73 0.68 0.90 FI, FR, IE, SE
Conservative 1
DEV*LIT*IND*STB 0.84 0.82 0.62 0.38 0.73 0.68 0.90 BE, CZ, FR, NL, SE, UK
Conservative 2
~DEV*~URB*LIT*~IND 0.46 0.15 0.22 0.05 0.72 0.67 0.88 EE, HU, PL
Conservative 2
DEV*LIT*IND*STB 0.84 0.82 0.62 0.51 0.72 0.67 0.88 BE, CZ, FR, NL, SE, UK
Conservative 2
~URB*LIT*~IND*STB 0.65 0.52 0.32 0.09 0.72 0.67 0.88 EE, FI, IE

Intermediate solution

qca_i_solution <- qca_solutions(i = i_solution, icp = "C1P1", round = 2)

print(qca_i_solution)
Solution Model Intermediate_CnPn Prime_Implicants Consistency_PI PRI_PI Raw_Coverage_PI Unique_Coverage_PI Solution_Consistency Solution_PRI Solution_Coverage Cases
Intermediate
C1P1 ~DEV*LIT 0.50 0.23 0.28 0.05 0.73 0.68 0.96 HU,PL; EE
Intermediate
C1P1 LIT*STB 0.79 0.76 0.92 0.69 0.73 0.68 0.96 EE; FI,IE; FR,SE; BE,CZ,NL,UK

Parsimonious solution

qca_p_solution <- qca_solutions(p = p_solution, round = 2)

print(qca_p_solution)
Solution Model Intermediate_CnPn Prime_Implicants Consistency_PI PRI_PI Raw_Coverage_PI Unique_Coverage_PI Solution_Consistency Solution_PRI Solution_Coverage Cases
Parsimonious 1
~DEV*LIT 0.50 0.23 0.28 0.08 0.73 0.68 0.90 EE, HU, PL
Parsimonious 1
DEV*STB 0.87 0.85 0.82 0.63 0.73 0.68 0.90 BE, CZ, FI, FR, IE, NL, SE, UK
Parsimonious 2
~DEV*LIT 0.50 0.23 0.28 0.05 0.73 0.68 0.96 EE, HU, PL
Parsimonious 2
LIT*STB 0.79 0.76 0.92 0.69 0.73 0.68 0.96 BE, CZ, EE, FI, FR, IE, NL, SE, UK
Parsimonious 3
DEV*STB 0.87 0.85 0.82 0.54 0.72 0.66 0.95 BE, CZ, FI, FR, IE, NL, SE, UK
Parsimonious 3
LIT*~IND 0.56 0.40 0.41 0.13 0.72 0.66 0.95 EE, FI, HU, IE, PL
Parsimonious 4
LIT*~IND 0.56 0.40 0.41 0.07 0.72 0.67 0.99 EE, FI, HU, IE, PL
Parsimonious 4
LIT*STB 0.79 0.76 0.92 0.58 0.72 0.67 0.99 BE, CZ, EE, FI, FR, IE, NL, SE, UK
Parsimonious 5
LIT*~IND 0.56 0.40 0.41 0.28 0.69 0.64 0.94 EE, FI, HU, IE, PL
Parsimonious 5
IND*STB 0.78 0.76 0.66 0.53 0.69 0.64 0.94 BE, CZ, FR, NL, SE, UK

Full usage, all solutions

qca_results <- qca_solutions(
  c = c_solution,            # Conservative solution object
  i = i_solution,            # Intermediate solution object
  icp = c("C1P3", "C2P1"),   # CnPn to include for intermediate solutions
  p = p_solution,            # Parsimonious solution object
  verbose = TRUE,            # Display progress messages
  round = 3,                 # Round numeric values to 3 decimal places
  incl.cut = 0.8,            # Set a consistency threshold for prime implicants
  save = "qca_results.xlsx"  # Save results to an Excel file
)
Solution Model Intermediate_CnPn Prime_Implicants Consistency_PI PRI_PI Raw_Coverage_PI Unique_Coverage_PI Solution_Consistency Solution_PRI Solution_Coverage Cases
Conservative 1
DEV*~URB*LIT*STB 0.809 0.761 0.433 0.110 0.734 0.679 0.898 FI, FR, IE, SE
Conservative 1
DEV*LIT*IND*STB 0.843 0.821 0.622 0.385 0.734 0.679 0.898 BE, CZ, FR, NL, SE, UK
Conservative 2
DEV*LIT*IND*STB 0.843 0.821 0.622 0.513 0.724 0.666 0.881 BE, CZ, FR, NL, SE, UK
Parsimonious 1
DEV*STB 0.869 0.848 0.824 0.628 0.731 0.676 0.904 BE, CZ, FI, FR, IE, NL, SE, UK
Parsimonious 3
DEV*STB 0.869 0.848 0.824 0.542 0.717 0.664 0.950 BE, CZ, FI, FR, IE, NL, SE, UK
Intermediate
C1P3 DEV*LIT*STB 0.869 0.848 0.824 0.542 0.717 0.664 0.950 FI,IE; FR,SE; BE,CZ,NL,UK
Intermediate
C2P1 LIT*IND*STB 0.829 0.806 0.664 0.371 0.736 0.686 0.958 FR,SE; BE,CZ,NL,UK

Bonus: nifty trick to save truth tables to Excel

library(dplyr)
library(tidyr)
library(writexl)

tt$tt %>%
  mutate(across(c(1:9), ~round(as.numeric(.), 2))) %>% # Fix numerical columns 1 to 9 and rounding
  arrange(desc(incl), desc(PRI)) %>% # Sort by consistency and PRI
  replace(is.na(.), "-") %>% # Replace empty cells with "-"
  write_xlsx("tt_file_name.xlsx") # Write to .xlsx file