Skip to content

Improve printing#48

Merged
BjarkeHautop merged 4 commits into
disco-coders:mainfrom
BjarkeHautop:main
Jun 19, 2026
Merged

Improve printing#48
BjarkeHautop merged 4 commits into
disco-coders:mainfrom
BjarkeHautop:main

Conversation

@BjarkeHautop

Copy link
Copy Markdown
Member

The old printing printed a lot, but didn't really show much. Redesigned the printing of Knowledge and Disco objects, what do you think @ekstroem? I can then use this in the JSS paper instead of having to use plots every time.

While redesigning I noticed you couldn't use + syntax in knowledge() for infix operators, such as
A + B %-->% C + D, and I fixed this too. To test this PR locally run

pak::pak("https://github.com/BjarkeHautop/causalDisco")

Showcase of output:

suppressPackageStartupMessages(library(causalDisco))
data("tpc_example")

# Only edge knowledge
kn <- knowledge(
  tpc_example,
  c(child_x1, oldage_x6) %-->% c(child_x2, youth_x3),
  child_x2 %!-->% c(youth_x3, oldage_x5)
)
kn
#> <Knowledge: 6 vars | 4 required | 2 forbidden>
#>   vars: child_x1, child_x2, oldage_x5, oldage_x6, youth_x3, youth_x4
#>   child_x1 %-->% child_x2 + youth_x3
#>   oldage_x6 %-->% child_x2 + youth_x3
#>   child_x2 %!-->% oldage_x5 + youth_x3

# Only tier knowledge:
kn2 <- knowledge(
  tpc_example,
  tier(
    1 ~ starts_with("child"),
    2 ~ starts_with("youth"),
    3 ~ starts_with("oldage")
  )
)
kn2
#> <Knowledge: 3 tiers | 6 vars>
#>   tier(1): child_x1, child_x2
#>   tier(2): youth_x3, youth_x4
#>   tier(3): oldage_x5, oldage_x6

# Both:
kn3 <- knowledge(
  tpc_example,
  child_x1 %-->% c(child_x2, youth_x3),
  child_x2 %!-->% c(youth_x3, oldage_x5),
  tier(
    1 ~ starts_with("child"),
    2 ~ starts_with("youth"),
    3 ~ starts_with("oldage")
  )
)
kn3
#> <Knowledge: 3 tiers | 6 vars | 2 required | 2 forbidden>
#>   tier(1): child_x1, child_x2
#>   tier(2): youth_x3, youth_x4
#>   tier(3): oldage_x5, oldage_x6
#>   child_x1 %-->% child_x2 + youth_x3
#>   child_x2 %!-->% oldage_x5 + youth_x3

pc_method <- pc(engine = "bnlearn", test = "fisher_z")
disco(tpc_example, pc_method)
#> <Disco PDAG: 6 nodes | 6 edges>
#>   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
disco(tpc_example, pc_method, kn)
#> <Disco PDAG: 6 nodes | 9 edges | Knowledge: 4 required, 2 forbidden>
#> Learned graph:
#>   nodes: child_x2, child_x1, youth_x4, youth_x3, oldage_x6, oldage_x5
#>   edges: child_x1-->child_x2, child_x1-->youth_x3, child_x2---youth_x4
#>          oldage_x5-->child_x2, oldage_x5-->oldage_x6, oldage_x5-->youth_x3
#>          oldage_x6-->child_x2, oldage_x6-->youth_x3, youth_x4-->oldage_x6
#> Knowledge:
#>   vars: child_x1, child_x2, oldage_x5, oldage_x6, youth_x3, youth_x4
#>   child_x1 %-->% child_x2 + youth_x3
#>   oldage_x6 %-->% child_x2 + youth_x3
#>   child_x2 %!-->% oldage_x5 + youth_x3
disco(tpc_example, pc_method, kn2)
#> <Disco PDAG: 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(1): child_x1, child_x2
#>   tier(2): youth_x3, youth_x4
#>   tier(3): oldage_x5, oldage_x6
disco(tpc_example, pc_method, kn3)
#> <Disco PDAG: 6 nodes | 6 edges | Knowledge: 3 tiers, 2 required, 2 forbidden>
#> Learned graph:
#>   nodes: child_x2, child_x1, youth_x4, youth_x3, oldage_x6, oldage_x5
#>   edges: child_x1-->child_x2, child_x1-->youth_x3, child_x2-->youth_x4
#>          oldage_x5-->oldage_x6, youth_x3-->oldage_x5, youth_x4-->oldage_x6
#> Knowledge:
#>   tier(1): child_x1, child_x2
#>   tier(2): youth_x3, youth_x4
#>   tier(3): oldage_x5, oldage_x6
#>   child_x1 %-->% child_x2 + youth_x3
#>   child_x2 %!-->% oldage_x5 + youth_x3




# Large data showcase:
large_data <- as.data.frame(
  matrix(
    runif(10000),
    nrow = 100,
    ncol = 100,
    byrow = TRUE
  )
)

names(large_data) <- paste0("X_", 1:100)

kn4 <- knowledge(
  large_data,
  tier(
    seq_tiers(
      1:100,
      ends_with("_{i}")
    )
  ),
  X_1 %-->% X_2
)
kn4
#> <Knowledge: 100 tiers | 100 vars | 1 required>
#>   tier(1): X_1
#>   tier(2): X_2
#>   tier(3): X_3
#>   tier(4): X_4
#>   tier(5): X_5
#>   ... and 95 more tiers
#>   X_1 %-->% X_2

disco(large_data, pc_method, kn4)
#> <Disco PDAG: 100 nodes | 96 edges | Knowledge: 100 tiers, 1 required>
#> Learned graph:
#>   nodes: X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8, X_9, X_10, ... and 90 more
#>   edges: X_1-->X_2, X_1-->X_49, X_12-->X_36, X_13-->X_40, X_13-->X_62
#>          X_14-->X_33, X_14-->X_97, X_16-->X_80, X_17-->X_82, X_17-->X_98
#>          ... and 86 more
#> Knowledge:
#>   tier(1): X_1
#>   tier(2): X_2
#>   tier(3): X_3
#>   tier(4): X_4
#>   tier(5): X_5
#>   ... and 95 more tiers
#>   X_1 %-->% X_2

Created on 2026-06-19 with reprex v2.1.1

Notes for myself:

  • Deprecate summary() and old args in print/summary
  • Add entry to news
  • Improve vignette and examples to use new syntax of knowledge for infix operators
  • Record graph class PAG since caugi doesn't support it yet. Then when printing PAGs we can say PAG instead of UNKNOWN.

Comment thread R/disco-class.R
Comment thread R/disco-class.R
Comment thread R/disco-class.R
Comment thread R/disco-class.R
Comment thread R/disco-class.R
Comment thread R/knowledge.R
@BjarkeHautop BjarkeHautop merged commit 90c14f2 into disco-coders:main Jun 19, 2026
2 of 4 checks passed
@BjarkeHautop

Copy link
Copy Markdown
Member Author

Whoops, sorry. Opened #49

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant