Skip to content

DAU Necessary Condition Analysis — Methods and Results

Created 2026-06-03
Status draft — pending Asia's review
Tags scienceanalysisNCAstatisticsDAU-frameworkBRNetinteroceptive-awareness

This document records the statistical analysis for the D/A/U prerequisite hypothesis. It includes the Python script, full methods, and results with interpretation. Poster-facing points are flagged at the end of each Results subsection.


Three formal claims are tested:

HypothesisStatementFormal notation
H1Discrimination is a necessary condition for AppraisalA → D (A=1 requires D=1)
H2Discrimination is a necessary condition for Use/SkillU → D (U=1 requires D=1)
H3Appraisal and Use/Skill are independent of each otherA ⊥ U | D=1

H1 and H2 operationalize the theoretical claim that D is the trained component from which A and U emerge. H3 asserts that A and U are distinct outcomes, not a single construct.


Participant-level binary coding from the DAU analysis spreadsheet (N = 39). Each participant was coded 0 or 1 for D, A, and U based on whether their testimonial or segment-feedback account contained evidence of that dimension in any body-representation domain. Coding was conducted manually; D/A/U boundaries are defined in project-outline.

Analysis 1 — Necessary Condition Analysis (NCA)

Section titled “Analysis 1 — Necessary Condition Analysis (NCA)”

Necessary Condition Analysis (Dul, 2016, Organizational Research Methods, 19(1), 10–55) was applied to test H1 and H2. NCA is designed specifically for “X is necessary for Y” claims, treating the hypothesis as a ceiling constraint rather than a correlation. Unlike regression or chi-square, NCA is not confounded by cases where X=1 and Y=0 (D present, A absent), which are theoretically expected under the prerequisite model.

For binary X (D) and Y (A or U), the key metrics are:

Consistency (NCA accuracy / QCA necessity consistency):

$$\text{Consistency} = \frac{\sum \min(X_i, Y_i)}{\sum Y_i} = \frac{n_{X=1,Y=1}}{n_{Y=1}}$$

This is the proportion of Y=1 cases where the necessary condition X is present. For binary variables, it equals P(D=1 | A=1) or P(D=1 | U=1). The accepted threshold for claiming a necessary condition is consistency ≥ 0.90 (Dul, 2016).

Coverage:

$$\text{Coverage} = \frac{n_{X=1,Y=1}}{n_{X=1}}$$

How much of the D=1 space is “used” by the outcome. Less central to the necessity claim; included for completeness.

Effect size d (ceiling envelopment approximation for binary data):

$$d = \frac{n_{D=0}}{n} \times \text{Consistency}$$

For binary variables, the NCA effect size reflects the fraction of the outcome space constrained by the necessary condition. When consistency = 1.0, it equals P(D=0) — the proportion of the X-axis that is entirely forbidden for Y=1. When violations exist, d is scaled down proportionally.

Permutation test: Statistical significance was assessed by permuting X labels (D) 10,000 times while holding Y (A or U) fixed, and counting the proportion of permutations that achieved consistency ≥ the observed value. This is the standard NCA significance test; it is more appropriate than chi-square here because the hypothesis is directional and asymmetric.

Analysis 2 — Fisher’s Exact Test for A–U Independence

Section titled “Analysis 2 — Fisher’s Exact Test for A–U Independence”

To test H3, a 2×2 contingency table was constructed for A and U among participants with D=1 only (n=32). Participants with D=0 were excluded, since the independence claim is conditional on D being present. Fisher’s exact test (two-tailed) was used rather than chi-square because two of the four cells have small counts. The phi coefficient was computed as an effect size measure.

All analyses were run in Python 3.9 using scipy.stats.fisher_exact. NCA metrics and the permutation test were implemented from first principles following Dul (2016). The script is reproduced in full in the Script section of this document.


The 39 participants produced the following D|A|U pattern distribution:

D|A|UDescriptionn%Consistent with H?
0|0|0No D, A, or U615.4%Yes
0|0|1U without D00.0%
0|1|0A without D12.6%No
0|1|1A+U without D00.0%
1|0|0D only (intermediate)25.1%Yes
1|0|1D+U, no A1435.9%Yes
1|1|0D+A, no U410.3%Yes
1|1|1Full D+A+U1230.8%Yes
Total39100%

38/39 participants (97.4%) showed a pattern consistent with the prerequisite hypothesis. The single inconsistent case is pattern 0|1|0 (Morten: A present, D absent, U absent). Zero participants showed U without D.

The 0|1|0 case (Morten). This is the only violation of H1. Coding notes record: “A=1 confirmed — attitudinal shift toward accepting current capacity rather than competing, appropriate for a former competitive footballer. D=0: no interoceptive detection language in this account.” The interview was conducted as a general free-response account, not structured to elicit D-level description. The attitudinal shift (A) described by Morten is cognitively framed (“you don’t have to push yourself to maximum every time”) rather than arising from explicit interoceptive detection events. This is consistent with under-ascertainment of D in a short, outcome-focused account. The case is retained as a violation rather than recoded, but is noted as likely a methodological artifact of the interview format.

Poster point: 38/39 participants (97.4%) showed patterns consistent with D as a prerequisite for both A and U. The single exception involved a participant whose account was cognitively framed and likely under-reported D-level interoceptive content.

HypothesisY casesViolationsConsistencyCoverageEffect size dp-value (permutation)
H1: D necessary for A1710.9410.5000.1690.095
H2: D necessary for U2601.0000.8120.179< 0.001

H1 (D necessary for A). Consistency = 0.941, above the accepted threshold of 0.90. Of the 17 participants reporting Appraisal outcomes, 16 also showed evidence of Discrimination. The permutation p-value is 0.095, which is above the conventional α = 0.05 threshold. This marginal result is expected given the small sample (N=39) and the one-violation structure: the permutation test is inherently limited in power when the signal is near-perfect but cell counts are small. The consistency score is the more interpretable metric for necessary condition claims at this sample size, and 0.941 unambiguously clears the 0.90 standard. H1 is supported by the pattern evidence.

H2 (D necessary for U). Consistency = 1.000 — perfect. No participant in the dataset reported Use/Skill outcomes without also showing evidence of Discrimination. The permutation p-value is < 0.001 (0 out of 10,000 shuffles produced consistency ≥ 1.000 by chance). H2 is fully supported.

Effect sizes. Both effect sizes are in the small-to-medium range (d = 0.169 and 0.179), reflecting the fact that D=0 accounts for 7/39 = 17.9% of the dataset. The ceiling constraint operates across roughly 18% of the outcome space — the segment of participants who showed no evidence of any D/A/U content. Effect size should not be interpreted as a strength-of-association metric here; it is a measure of how much of the parameter space is constrained by the necessary condition.

Poster points:

  • Both necessary condition claims meet the ≥0.90 consistency threshold (0.941 and 1.000).
  • D necessary for U is perfect and highly significant.
  • D necessary for A is near-perfect (one likely ascertainment gap), permutation p = 0.095 at N=39.

A–U Conditional Independence (given D=1)

Section titled “A–U Conditional Independence (given D=1)”

Among the 32 participants with D=1:

U=0U=1Total
A=021416
A=141216
Total62632

Fisher’s exact test (two-tailed): OR = 0.43, p = 0.654. Phi coefficient = −0.16.

The result is non-significant. There is no evidence of association between A and U among D=present participants. The observed joint probability P(A=1, U=1 | D=1) = 0.375 is close to the expected value under independence (0.406). The slight trend toward a negative association (OR < 1, meaning A-present participants are slightly less likely to also have U) is not significant and is consistent with sampling noise at n=32.

Marginal rates: P(A=1 | D=1) = 0.50 and P(U=1 | D=1) = 0.81. U is substantially more prevalent than A in the D=1 population — consistent with the theoretical position that U emerges earlier and more universally than A in Baseworks training.

Poster points:

  • A and U are statistically independent of each other (Fisher’s p = 0.65) — they are distinct outcome dimensions, not a single construct.
  • U is more prevalent than A (81% vs. 50% of D-present participants), consistent with U being an earlier emergent outcome.

ClaimResultMetric
D is necessary for ASupportedConsistency = 0.941, 1/17 violations
D is necessary for UFully supportedConsistency = 1.000, 0/26 violations
A and U are independentSupportedFisher’s p = 0.654, OR = 0.43

Poster-ready summary (N = 39):

HypothesisCases testedViolationsConsistencyp-valueVerdict
H1: D necessary for A17 (A=1)1 (5.9%)0.9410.095Supported
H2: D necessary for U26 (U=1)0 (0%)1.000< 0.001Fully supported
H3: A and U independent given D=1n = 320.654 (Fisher’s)Independent

The data support the hierarchical prerequisite model: interoceptive Discrimination (D) is the condition upon which Appraisal (A) and Use/Skill (U) depend, while A and U develop independently of each other. This is consistent with the Baseworks training model, in which only D is explicitly targeted through intensity modification and natural breathing, while A and U are reported spontaneously by participants as consequential outcomes.


  1. Sample size. N=39 limits permutation test power, particularly for H1 (p=0.095). With a larger N, the same 1-violation pattern would produce a more significant p-value.
  2. Interview design. Testimonials were not collected with the D/A/U framework in mind. Free-response format likely underestimates D in accounts that are outcome-focused (as in the Morten case). This creates a bias toward finding violations of H1 and H2, not against them — the actual consistency rates may be higher than observed.
  3. Binary coding. Participant-level binary coding collapses intensity of evidence. Participants with a single D statement and participants with rich multi-instance D evidence are coded identically.
  4. Cross-domain contamination. 8 participants have Mixed=1 flag, meaning their D/A/U evidence includes spatial/proprioceptive content alongside or instead of interoceptive content. Figure 2 in the poster will require a domain qualifier for these cases.

#!/usr/bin/env python3
"""
DAU Necessary Condition Analysis
Baseworks INT-D-A-U project, BRNet 2026
Tests:
H1: D is a necessary condition for A (A → D)
H2: D is a necessary condition for U (U → D)
H3: A and U are conditionally independent given D=1
Run from the INT-D-A-U directory:
python3 dau-nca.py
"""
import csv
import math
import random
from collections import Counter
from scipy.stats import fisher_exact
# ── 1. Load data ──────────────────────────────────────────────────────────────
DATA_PATH = "dau-analysis.csv"
def load_dau(path):
rows = []
with open(path, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
rows.append({
"participant": row["Participant"],
"D": int(row["D"]),
"A": int(row["A"]),
"U": int(row["U"]),
})
return rows
data = load_dau(DATA_PATH)
n = len(data)
D = [r["D"] for r in data]
A = [r["A"] for r in data]
U = [r["U"] for r in data]
# ── 2. Pattern frequency table ────────────────────────────────────────────────
patterns = Counter((r["D"], r["A"], r["U"]) for r in data)
print(f"\n{'='*62}")
print(f" DAU Pattern Frequencies (N = {n})")
print(f"{'='*62}")
print(f" {'D|A|U':<8} {'Label':<34} {'n':>4} {'%':>6} {'H?'}")
print(f" {'-'*58}")
pattern_order = [(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1)]
labels = {
(0,0,0): "No D, A, or U",
(0,0,1): "U without D [violates H2]",
(0,1,0): "A without D [violates H1]",
(0,1,1): "A+U without D [violates both]",
(1,0,0): "D only (intermediate state)",
(1,0,1): "D+U, no A",
(1,1,0): "D+A, no U",
(1,1,1): "Full D+A+U",
}
n_consistent = 0
n_violating = 0
for p in pattern_order:
c = patterns.get(p, 0)
consistent = p[1] <= p[0] and p[2] <= p[0]
tag = "Yes" if consistent else "NO <--"
if consistent:
n_consistent += c
else:
n_violating += c
label = labels[p]
print(f" {str(p[0])+'|'+str(p[1])+'|'+str(p[2]):<8} {label:<34} {c:>4} {100*c/n:5.1f}% {tag}")
print(f" {'-'*58}")
print(f" Consistent with H: {n_consistent}/{n} = {100*n_consistent/n:.1f}%")
print(f" Violations: {n_violating}/{n} = {100*n_violating/n:.1f}%")
# ── 3. NCA for binary data ────────────────────────────────────────────────────
#
# Necessary Condition Analysis (Dul, 2016, ORM) for binary X and Y.
#
# Key metrics:
# Consistency = P(X=1 | Y=1) — proportion of Y=1 cases where condition holds.
# Dul's "accuracy" for the ceiling line; QCA necessity consistency.
# Threshold for accepting necessity: ≥ 0.90 (Dul 2016).
#
# Coverage = P(Y=1 | X=1) — how much of the X=1 space is "used" by Y=1.
#
# Effect size d = (n_X0 / n) × consistency
# Approximates the fraction of the [0,1]×[0,1] outcome space
# that is constrained by the necessary condition. Derived from
# the ceiling envelopment (CE) area for binary scatter plots:
# when there are no violations, the X=0 column is entirely
# forbidden for Y=1, giving d = P(X=0). When violations exist,
# d is scaled down proportionally.
#
# p-value = permutation test (10,000 shuffles of X, Y fixed).
# Tests H0: no necessary-condition relationship (X and Y
# independent). Reports the fraction of permutations achieving
# consistency ≥ observed.
def nca_binary(X_vals, Y_vals, x_label, y_label, n_perm=10_000, seed=42):
n = len(X_vals)
n_Y1 = sum(Y_vals)
n_X1_Y1 = sum(x and y for x, y in zip(X_vals, Y_vals))
n_X0_Y1 = n_Y1 - n_X1_Y1
n_X1 = sum(X_vals)
n_X0 = n - n_X1
consistency = n_X1_Y1 / n_Y1 if n_Y1 > 0 else float("nan")
coverage = n_X1_Y1 / n_X1 if n_X1 > 0 else float("nan")
d = (n_X0 / n) * consistency
rng = random.Random(seed)
X_pool = list(X_vals)
extreme = 0
for _ in range(n_perm):
rng.shuffle(X_pool)
perm_n_X1_Y1 = sum(x and y for x, y in zip(X_pool, Y_vals))
perm_consistency = perm_n_X1_Y1 / n_Y1
if perm_consistency >= consistency:
extreme += 1
p_value = extreme / n_perm
return dict(
x_label=x_label, y_label=y_label, n=n,
n_Y1=n_Y1, n_violations=n_X0_Y1,
consistency=consistency, coverage=coverage, d=d,
p_value=p_value, n_perm=n_perm,
)
# ── 4. Run NCA ────────────────────────────────────────────────────────────────
print(f"\n{'='*62}")
print(" Necessary Condition Analysis (Dul 2016)")
print(f"{'='*62}")
nca_results = []
for (X_vals, x_lbl, Y_vals, y_lbl) in [(D, "D", A, "A"), (D, "D", U, "U")]:
r = nca_binary(X_vals, Y_vals, x_lbl, y_lbl)
nca_results.append(r)
verdict = ("SUPPORTED (consistency ≥ 0.90)"
if r["consistency"] >= 0.90
else "NOT SUPPORTED (consistency < 0.90)")
print(f"\n H: {x_lbl} is necessary for {y_lbl} ({y_lbl}{x_lbl})")
print(f" {''*52}")
print(f" Cases where {y_lbl}=1: {r['n_Y1']:>3}")
print(f" Violations ({y_lbl}=1 but {x_lbl}=0): {r['n_violations']:>3}")
print(f" Consistency (NCA accuracy): {r['consistency']:.3f}")
print(f" Coverage: {r['coverage']:.3f}")
print(f" Effect size d: {r['d']:.3f}")
print(f" Permutation p-value (n={r['n_perm']:,}): {r['p_value']:.4f}")
print(f" Verdict: {verdict}")
# ── 5. Fisher's exact — A–U conditional independence given D=1 ─────────────────
print(f"\n{'='*62}")
print(" A–U Conditional Independence (given D=1)")
print(f"{'='*62}")
d1_pairs = [(r["A"], r["U"]) for r in data if r["D"] == 1]
n_d1 = len(d1_pairs)
a0u0 = sum(1 for a, u in d1_pairs if a == 0 and u == 0)
a0u1 = sum(1 for a, u in d1_pairs if a == 0 and u == 1)
a1u0 = sum(1 for a, u in d1_pairs if a == 1 and u == 0)
a1u1 = sum(1 for a, u in d1_pairs if a == 1 and u == 1)
table = [[a0u0, a0u1], [a1u0, a1u1]]
odds_ratio, p_val = fisher_exact(table, alternative="two-sided")
phi_num = a1u1 * a0u0 - a1u0 * a0u1
phi_den = math.sqrt((a1u1 + a1u0) * (a0u1 + a0u0) * (a1u1 + a0u1) * (a1u0 + a0u0))
phi = phi_num / phi_den if phi_den > 0 else float("nan")
p_A1 = (a1u0 + a1u1) / n_d1
p_U1 = (a0u1 + a1u1) / n_d1
p_AU1_expected = p_A1 * p_U1
p_AU1_observed = a1u1 / n_d1
print(f"\n Contingency table (D=1 only, n = {n_d1}):")
print(f" {'':>10} {'U=0':>6} {'U=1':>6} {'Total':>7}")
print(f" {'A=0':>10} {a0u0:>6} {a0u1:>6} {a0u0+a0u1:>7}")
print(f" {'A=1':>10} {a1u0:>6} {a1u1:>6} {a1u0+a1u1:>7}")
print(f" {'Total':>10} {a0u0+a1u0:>6} {a0u1+a1u1:>6} {n_d1:>7}")
print(f"\n Fisher's exact test (two-tailed):")
print(f" Odds ratio: {odds_ratio:.3f}")
print(f" p-value: {p_val:.4f}")
print(f" Phi coefficient (effect size): {phi:.3f}")
print(f"\n Marginal independence check:")
print(f" P(A=1 | D=1) = {p_A1:.3f}")
print(f" P(U=1 | D=1) = {p_U1:.3f}")
print(f" P(A=1,U=1 | D=1) — observed: {p_AU1_observed:.3f}")
print(f" P(A=1,U=1 | D=1) — under independence:{p_AU1_expected:.3f}")
if p_val > 0.05:
verdict = "No significant association (p > 0.05) — consistent with independence"
else:
verdict = "Significant association detected (p ≤ 0.05)"
print(f" Verdict: {verdict}")
print(f"\n{'='*62}")
print(" Analysis complete.")
print(f"{'='*62}\n")

Dul, J. (2016). Necessary condition analysis (NCA): Logic and methodology of “necessary but not sufficient” causality. Organizational Research Methods, 19(1), 10–55. https://doi.org/10.1177/1094428115571990