# Reading qcaERT result objects

qcaERT functions are designed as siblings. The details differ by test, but the main returned-object structure is intentionally shared.

The code fragments in this vignette use object names such as `incl_out`, `calib_out`, and `cluster_out`. The getting-started vignette shows how to create those objects in a normal QCA workflow.

Most robustness objects contain:

- `results`: the clean table
- `diagnostics`: the detailed table for inspection and troubleshooting
- `settings`: the arguments and derived settings used in the run
- supporting components such as `baseline`, `bounds`, `by_direction`, `by_case`, `by_run`, `by_draw`, or `summary`

Main summaries are:

    print(x)
    as.data.frame(x)
    x$results
    x$diagnostics

`print(x)` gives a concise summary. `as.data.frame(x)` returns the clean table. `x$diagnostics` is where to look when you need to understand a specific run, case, draw, or stopping reason.

## Boundary tests

`incl.test()`, `ncut.test()`, and `calib.test()` are boundary tests. They move a quantity away from the baseline until either the monitored solution changes, an error occurs, or the search reaches a limit.

    as.data.frame(incl_out)
    incl_out$diagnostics
    incl_out$bounds

    as.data.frame(ncut_out)
    ncut_out$diagnostics
    ncut_out$bounds

    as.data.frame(calib_out)
    calib_out$diagnostics
    calib_out$bounds

The clean table answers the practical question: how far did the value move before the result stopped being stable?

The diagnostics table preserves the path-level detail.

## Case and sample tests

`loo.test()` gives one row per removed case. `subsample.test()` gives one row per subsample run.

    as.data.frame(loo_out)
    loo_out$diagnostics
    loo_out$by_case

    as.data.frame(subsample_out)
    subsample_out$diagnostics
    subsample_out$by_run
    subsample_out$summary

Use the clean table to find cases or runs that changed the solution. Use the supporting list components when you need the full run object for a specific case or replication.

## Alternative-set tests

`altset.test()` gives one row per random draw. The result object also stores the draw-level run details and aggregate scores.

    as.data.frame(altset_out)
    altset_out$diagnostics
    altset_out$by_draw
    altset_out$summary

The clean table is for scanning. The summary component is for stability scores across all draws. When calibration is part of the sampled draw, `changed_sets` names the perturbed calibrated sets and `changed_roles` records whether those sets were conditions, the outcome, or both.

## Cluster tests

`cluster.test()` and `theory.test()` are the deliberate structured-result exceptions. For `cluster.test()`, `results` is a list:

- `overview`
- `clusters`
- `units`

    cluster_out$results$overview
    cluster_out$results$clusters
    cluster_out$results$units

    as.data.frame(cluster_out)
    cluster_out$diagnostics

For `cluster.test()`, `as.data.frame(cluster_out)` returns `cluster_out$results$overview`.

## Theory tests

`theory.test()` is also structured because comparative theory testing has three natural clean tables:

- `models`
- `solutions`
- `pairwise`

    as.data.frame(theory_out)
    theory_out$results$models
    theory_out$results$solutions
    theory_out$results$pairwise
    theory_out$diagnostics
    theory_out$by_theory

For `theory.test()`, `as.data.frame(theory_out)` returns `theory_out$results$models`. Inspect `results$solutions` when the question is which terms were selected, and inspect `results$pairwise` when the question is how far selected solution memberships differ across theories.

## Solution tables

`sol.df()` returns a regular data frame directly.

    tab <- sol.df(intermediate = sol, solution = "intermediate")
    tab
    is.data.frame(tab)

Use `sol.df()` when you want to report or inspect QCA minimization output in a compact table.

## What to inspect first

In normal use, inspect objects in this order:

1. Print the object.
2. Call `as.data.frame(x)` for the clean table.
3. Look at `x$summary` if the function has one.
4. Open `x$diagnostics` only when you need the full detail.
5. For `cluster.test()`, inspect `x$results$clusters` and `x$results$units` after checking the overview.
6. For `theory.test()`, inspect `x$results$solutions` and `x$results$pairwise` after checking the model table.

The same conventions are described formally in `?qcaERT_conventions`.