Tests whether a condition is both necessary and sufficient for an outcome, that is, whether the outcome cannot be reached without the condition and is guaranteed in its presence. Such a claim implies that two diagonally opposite corners of the condition-outcome scatter plot contain no observations. The package estimates both boundaries with the same data, scope and frontier technique, reports the effect size and permutation test of each, and indicates joint support only when both components are supported. The two components are summarized by the weaker effect, a balanced combination and the proportion of the scope that the two claims jointly rule out. A dual-threshold table gives, for each outcome level, the condition level it requires, the level sufficient for it, and the interval between them. Results can be compared with regression slopes. The package also provides plots, influential-case diagnostics, scope-sensitivity and resampling checks, and simulation and power analysis for planning studies. The two sides are estimated with the 'NCA' and 'SCAtools' packages.
Necessary and Sufficient Condition Analysis (NSCA) in R.
A condition is necessary for an outcome when the outcome does not occur without it, and sufficient when the presence of the condition guarantees the outcome. A condition that is both necessary and sufficient defines a dividing line at each level of the outcome: below the line, that level cannot be reached; above it, that level is guaranteed.
Each half of this claim implies a specific prediction about the data. When the condition X is plotted against the outcome Y, necessity implies that one corner of the scatter plot is empty, and sufficiency implies that the diagonally opposite corner is empty. For the claim "high X is necessary and sufficient for high Y", there should be no cases with low X and high Y (upper-left) and none with high X and low Y (lower-right).
NSCA estimates both empty corners from the same data, with the same scope and the same frontier technique. It measures each corner, tests each against random pairing of X and Y, and assesses the two jointly. The band between the two frontiers is the admissible region, the set of combinations that neither claim rules out. The narrower this region, the closer the relationship is to a strict necessary-and-sufficient relationship.
| Direction | Claim | Necessity corner | Sufficiency corner |
|---|---|---|---|
HH |
high X is necessary and sufficient for high Y | upper-left | lower-right |
LH |
low X is necessary and sufficient for high Y | upper-right | lower-left |
HL |
high X is necessary and sufficient for low Y | lower-left | upper-right |
LL |
low X is necessary and sufficient for low Y | lower-right | upper-left |
nsca_compare() reports the
regression slope beside both effect sizes, so that a study can indicate
whether the data display an average effect, a condition effect, or both.nsca_power() estimates the number of observations
needed to detect both components.install.packages("NSCA")
This also installs NCA, which estimates the necessity side, and SCAtools, which estimates the sufficiency side.
library(NSCA)
# Simulated data lying in a band, so both corners are empty
set.seed(1)
dat <- nsca_random(n = 100, d_nec = 0.3, d_suf = 0.3)
# 1. Fit the claim "high X is necessary and sufficient for high Y"
fit <- nsca_analysis(dat, x = "X", y = "Y", direction = "HH",
test.rep = 1000)
fit # all three layers, with every setting the result rests on
# 2. Read the results
nsca_results(fit) # the necessity, sufficiency and joint tables
nsca_table(fit) # the joint table and the joint-support decision
nsca_thresholds(fit) # required level, guaranteeing level and the interval
nsca_plot(fit) # both frontiers and the admissible region
# 3. Set it beside regression
nsca_compare(fit)
nsca() runs the same analysis, including the permutation tests, and draws
the plot in one step. nsca_output() prints the tables and draws the plots
typically needed for a report:
nsca(dat, x = "X", y = "Y", direction = "HH")
nsca_output(fit, thresholds = TRUE, tests = TRUE)
| Function | What it shows |
|---|---|
nsca_test_plot() |
both permutation distributions beside the observed effect sizes |
nsca_shared_plot() |
the shared permutation distributions of both sides, their minimum and their sum |
nsca_scope() |
the scope by which both effect sizes were divided |
nsca_scope_sensitivity() |
how both components and the joint summaries change with the scope |
nsca_resample() |
how much they vary across subsamples |
nsca_outliers() |
which observations determine each frontier |
nsca_locationshift() |
whether each frontier is a level shift or a threshold |
nsca_magnitude() |
conventional magnitude bands for a component effect size |
The two components. d_nec and d_suf are the empty areas as
proportions of the scope, ranging from 0 to 1. d_nec_null and d_suf_null,
reported beside them, are the values that random pairing of the same data
produces. d_nec_critical and d_suf_critical are the values that random
pairing exceeds only 5% of the time, that is, the critical values of the two
components in a single test. When several conditions are analyzed,
nsca_table(fit, p.adjust = "holm") adjusts the p-values for multiple
testing; the critical values remain single-test reference lines.
Three joint summaries.
| Column | What it asks |
|---|---|
weakest_effect |
how strong the weaker of the two claims is |
balanced_joint_effect |
how strong the two are together, with higher values when they are balanced |
joint_empty_space_coverage |
how much of the scope the two claims together rule out |
nsca_joint() computes the full family of summaries between these, from no
compensation between the components to full compensation.
The p-values. Each p-value addresses a different question, and
joint_support uses the first:
| Column | What it asks |
|---|---|
p_nsca_iut |
is each corner emptier than under random pairing? max(p_nec, p_suf) |
p_weakest_perm |
is the smaller empty area larger than random pairing produces? |
p_sum_perm |
are the two corners together emptier than under random pairing? |
p_nsca_iut is significant only when both component tests reject, so
combining them requires no correction. The other two require
shared.test.rep, which applies the same shuffles to both sides. A single
strongly empty corner may by itself make p_sum_perm small. We suggest
choosing the p-value that addresses the research question before reading the
results.
Joint support. joint_support is TRUE when both components are
significant, both reach the relevance threshold if one was set with
relevance =, and the two frontiers have an acceptable geometry. The
individual flags beside it indicate which requirements each row meets.
Dual thresholds. For a high-X direction, each outcome level divides the X axis into three parts:
| X | The outcome level is |
|---|---|
below necessity_threshold |
not attainable |
| between the two thresholds | possible but not guaranteed |
above sufficiency_threshold |
guaranteed |
For a low-X direction, the inequalities are reversed.
necessity_sufficiency_interval is the width of the middle part;
threshold_status reports exact correspondence where this width is zero.
nsca_scope() and the printed
Settings block record it.relevance =.nsca_magnitude()); for the joint
summaries, nsca_power() and nsca_resample() indicate which values the
design can produce.An ordinary least-squares or median regression line can be added with
reference = "ols" or "qr". It is drawn for comparison and reported by
nsca_reference(); it is not part of either component.
?NSCA describes the method and lists its references.citation("NSCA") gives the references to cite.nsca_terms() lists the vocabulary used in the tables, and
nsca_legacy_names() maps names used by earlier versions to the current
ones.system.file("examples", "necessary-and-sufficient.R", package = "NSCA")
provides a worked example.Source and issue tracker: https://github.com/youngchanresearcher/NSCA
The Traditional Chinese version of this README is installed with the package:
file.show(system.file("docs", "README_zh-TW.md", package = "NSCA"))