jtextor / dagitty

Graphical analysis of structural causal models / graphical causal models.
GNU General Public License v2.0
255 stars 47 forks source link

markovBlanket() bugs with fix #58

Closed behrman closed 2 years ago

behrman commented 2 years ago

Below is some code using dagitty version 0.3-1 and the graph from this example code.

library(dagitty)

fig_2.9 <- 
  dagitty(
    'dag{
      W -> Y
      X -> W
      Z_1 -> {X Z_3}
      Z_2 -> {Y Z_3}
      Z_3 -> {X Y}
    }'
  )

markovBlanket(fig_2.9, "Z_1")
#> Warning in if (!(v %in% names(x))) stop(paste(v, "is not a variable in `x`")):
#> the condition has length > 1 and only the first element will be used
#> [1] "X"   "Z_3" "Z_2"

markovBlanket(fig_2.9, "Y")
#> Error in if (!(v %in% names(x))) stop(paste(v, "is not a variable in `x`")): argument is of length zero

Created on 2022-03-04 by the reprex package (v2.0.1)

The warning and error come from dagitty:::.checkName(). The warning is because Z_1 has more than on child. The error is because Y has no children.

The following code fixes these problems.

library(dagitty)
library(purrr)

fig_2.9 <- 
  dagitty(
    'dag{
      W -> Y
      X -> W
      Z_1 -> {X Z_3}
      Z_2 -> {Y Z_3}
      Z_3 -> {X Y}
    }'
  )

markov_blanket <- function(graph, nodes) {
  map_nodes <- function(nodes, .f) {
    nodes %>% 
      map(.f, x = graph) %>% 
      unlist()
  }
  nodes %>% 
    map_nodes(children) %>% 
    map_nodes(parents) %>% 
    union(nodes %>% map_nodes(parents)) %>% 
    union(nodes %>% map_nodes(children)) %>% 
    setdiff(nodes) %>% 
    sort()
}

markov_blanket(fig_2.9, list())
#> NULL

markov_blanket(fig_2.9, "Z_1")
#> [1] "X"   "Z_2" "Z_3"

markov_blanket(fig_2.9, "Y")
#> [1] "W"   "Z_2" "Z_3"

markov_blanket(fig_2.9, c("W", "Y"))
#> [1] "X"   "Z_2" "Z_3"

Created on 2022-03-04 by the reprex package (v2.0.1)

jtextor commented 2 years ago

Thanks for letting me know! I hope it's OK that I didn't use your code, since the underlying issue was in the .kins function, so I fixed that instead. I added your example as a further unit tests and it's working as expected now. Thank you for your contribution!

behrman commented 2 years ago

Great. Thanks for the quick fix!