Run a tier-aware variant of the PC algorithm that respects background
knowledge about a partial temporal order. Supply the temporal order via a
Knowledge object.
Usage
tpc_run(
data = NULL,
knowledge = NULL,
alpha = 0.05,
test = reg_test,
suff_stat = NULL,
method = "stable.fast",
na_method = "none",
orientation_method = "conservative",
directed_as_undirected = lifecycle::deprecated(),
varnames = NULL,
num_cores = 1,
...
)Arguments
- data
A data frame with the observed variables.
- knowledge
A
Knowledgeobject created withknowledge(), encoding tier assignments and optional forbidden/required edges. This is the preferred way to provide temporal background knowledge.- alpha
The alpha level used as the per-test significance threshold for conditional independence testing.
- test
A conditional independence test. The default
reg_test()uses a regression-based information-loss test. Another available option iscor_test()which tests for vanishing partial correlations. User-supplied functions may also be used; see details for the required interface.- suff_stat
A sufficient statistic. If supplied, it is passed directly to the test and no statistics are computed from
data. Its structure depends on the chosentest.- method
Skeleton construction method, one of
"stable","original", or"stable.fast"(default). Seepcalg::skeleton()for details.- na_method
Handling of missing values, one of
"none"(default; error on anyNA),"cc"(complete-case analysis), or"twd"(test-wise deletion).- orientation_method
Conflict-handling method when orienting edges. Currently only the conservative method is available.
- directed_as_undirected
This argument no longer has any effect and will be removed in a future release. Directed forbidden edges are now resolved using tier information, or must be specified in both directions.
- varnames
Character vector of variable names. Only needed when
datais not supplied and all information is passed viasuff_stat.- num_cores
Integer number of CPU cores to use for parallel skeleton learning.
- ...
Additional arguments passed to
pcalg::skeleton()during skeleton construction.
Details
Any independence test implemented in pcalg may be used; see
pcalg::pc(). When na_method = "twd", test-wise deletion is
performed: for cor_test(), each pairwise correlation uses complete cases;
for reg_test(), each conditional test performs its own deletion. If you
supply a user-defined test, you must also provide suff_stat.
Temporal or tiered knowledge enters in two places:
during skeleton estimation, candidate conditioning sets are pruned so they do not contain variables that are strictly after both endpoints;
during orientation, any cross-tier edge is restricted to point forward in time.
Recommendation
While it is possible to call the function returned directly with a data frame,
we recommend using disco(). This provides a consistent interface and handles knowledge
integration.
Value
A function that takes a single argument data (a data frame). When called,
this function returns a list containing:
knowledgeAKnowledgeobject with the background knowledge used in the causal discovery algorithm. Seeknowledge()for how to construct it.caugiAcaugi::caugiobject (of classPDAG) representing the learned causal graph from the causal discovery algorithm.
Examples
# Load data
data(tpc_example)
# Build knowledge
kn <- knowledge(
tpc_example,
tier(
child ~ tidyselect::starts_with("child"),
youth ~ tidyselect::starts_with("youth"),
old ~ tidyselect::starts_with("old")
)
)
# Recommended route using disco
my_tpc <- tpc(engine = "causalDisco", test = "fisher_z", alpha = 0.05)
disco(tpc_example, my_tpc, knowledge = kn)
#> <Disco MPDAG: 6 nodes | 6 edges | Knowledge: 3 tiers>
#> Learned graph:
#> nodes: child_x2, child_x1, youth_x4, youth_x3, oldage_x6, oldage_x5
#> edges: child_x1---child_x2, child_x2-->oldage_x5, child_x2-->youth_x4
#> oldage_x5-->oldage_x6, youth_x3-->oldage_x5, youth_x4-->oldage_x6
#> Knowledge:
#> tier(child): child_x1, child_x2
#> tier(youth): youth_x3, youth_x4
#> tier(old): oldage_x5, oldage_x6
# or using my_tpc directly
my_tpc <- my_tpc |> set_knowledge(kn)
my_tpc(tpc_example)
#> <Disco UNKNOWN: 6 nodes | 6 edges | Knowledge: 3 tiers>
#> Learned graph:
#> nodes: child_x2, child_x1, youth_x4, youth_x3, oldage_x6, oldage_x5
#> edges: child_x1---child_x2, child_x2-->oldage_x5, child_x2-->youth_x4
#> oldage_x5-->oldage_x6, youth_x3-->oldage_x5, youth_x4-->oldage_x6
#> Knowledge:
#> tier(child): child_x1, child_x2
#> tier(youth): youth_x3, youth_x4
#> tier(old): oldage_x5, oldage_x6
# Using tpc_run() directly
tpc_run(tpc_example, knowledge = kn, alpha = 0.01)
#> <Disco UNKNOWN: 6 nodes | 6 edges | Knowledge: 3 tiers>
#> Learned graph:
#> nodes: child_x2, child_x1, youth_x4, youth_x3, oldage_x6, oldage_x5
#> edges: child_x1---child_x2, child_x2-->oldage_x5, child_x2-->youth_x4
#> oldage_x5-->oldage_x6, youth_x3-->oldage_x5, youth_x4-->oldage_x6
#> Knowledge:
#> tier(child): child_x1, child_x2
#> tier(youth): youth_x3, youth_x4
#> tier(old): oldage_x5, oldage_x6
