Skip to content

Commit

Permalink
proper ancestors and descendants
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Textor committed Apr 6, 2022
1 parent 3a8969c commit ca4ec74
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 20 deletions.
17 changes: 13 additions & 4 deletions gui/js/dagitty.js
Original file line number Diff line number Diff line change
Expand Up @@ -4541,7 +4541,7 @@ var GraphTransformer = {
}
})
})

// Delete all vertices that have not been marked for retention
if( opts.direct ){
_.each( intermediates_after_source, function(v){ retain[v.id] = true } )
Expand All @@ -4551,7 +4551,7 @@ var GraphTransformer = {
g_chain.deleteVertex(v)
}
} )

// Restore original edge types
var edges_to_replace = []
_.each( g_chain.edges, function(e){
Expand All @@ -4567,7 +4567,8 @@ var GraphTransformer = {
g_chain.addEdge( e.v2.id, e.v1.id, Graph.Edgetype.Directed )
}
} )



// Replace dummy nodes from canonical graph with original nodess
var Lids = _.pluck(g_canon.L,"id"), Sids = _.pluck(g_canon.S,"id")
L=[], S=[]
Expand All @@ -4582,17 +4583,25 @@ var GraphTransformer = {

// For direct effects, add causal paths between mediators
if( opts.direct ){
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources() ),
_.each( Z, Graph.Vertex.markAsVisited )
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources(), preserve_previous_visited_information ),
g.ancestorsOf( g.getTargets() ) ) )
_.each( gind.edges, function(e){
if( e.directed == Graph.Edgetype.Directed && !(
(gind.isSource(e.v1)||gind.isTarget(e.v1)) && (gind.isSource(e.v2)||gind.isTarget(e.v2))) ){
if( !g_chain.getVertex( e.v1.id ) ){
g_chain.addVertex( e.v1.id )
}
if( !g_chain.getVertex( e.v2.id ) ){
g_chain.addVertex( e.v2.id )
}
g_chain.addEdge( e.v1.id, e.v2.id, Graph.Edgetype.Directed )
}
})
}
g = GraphTransformer.decanonicalize( g_chain, L, S )
g.setType( in_type )

return g
}, // end of activeBiasGraph

Expand Down
17 changes: 13 additions & 4 deletions jslib/graph/GraphTransformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ var GraphTransformer = {
}
})
})

// Delete all vertices that have not been marked for retention
if( opts.direct ){
_.each( intermediates_after_source, function(v){ retain[v.id] = true } )
Expand All @@ -774,7 +774,7 @@ var GraphTransformer = {
g_chain.deleteVertex(v)
}
} )

// Restore original edge types
var edges_to_replace = []
_.each( g_chain.edges, function(e){
Expand All @@ -790,7 +790,8 @@ var GraphTransformer = {
g_chain.addEdge( e.v2.id, e.v1.id, Graph.Edgetype.Directed )
}
} )



// Replace dummy nodes from canonical graph with original nodess
var Lids = _.pluck(g_canon.L,"id"), Sids = _.pluck(g_canon.S,"id")
L=[], S=[]
Expand All @@ -805,17 +806,25 @@ var GraphTransformer = {

// For direct effects, add causal paths between mediators
if( opts.direct ){
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources() ),
_.each( Z, Graph.Vertex.markAsVisited )
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources(), preserve_previous_visited_information ),
g.ancestorsOf( g.getTargets() ) ) )
_.each( gind.edges, function(e){
if( e.directed == Graph.Edgetype.Directed && !(
(gind.isSource(e.v1)||gind.isTarget(e.v1)) && (gind.isSource(e.v2)||gind.isTarget(e.v2))) ){
if( !g_chain.getVertex( e.v1.id ) ){
g_chain.addVertex( e.v1.id )
}
if( !g_chain.getVertex( e.v2.id ) ){
g_chain.addVertex( e.v2.id )
}
g_chain.addEdge( e.v1.id, e.v2.id, Graph.Edgetype.Directed )
}
})
}
g = GraphTransformer.decanonicalize( g_chain, L, S )
g.setType( in_type )

return g
}, // end of activeBiasGraph

Expand Down
24 changes: 20 additions & 4 deletions r/R/dagitty.r
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ impliedCovarianceMatrix <- function( x, b.default=NULL, b.lower=-.6, b.upper=.6,
#'
#' @param x the input graph, of any type.
#' @param v name(s) of variable(s).
#' @param proper logical. By default (\code{proper=FALSE}), the \code{descendants} or \code{ancestors}
#' of a variable include the variable itself. For (\code{proper=TRUE}), the variable itself
#' is not included.
#'
#' \code{descendants(x,v)} retrieves variables that are are reachable from \code{v} via
#' a directed path.
Expand All @@ -435,22 +438,35 @@ impliedCovarianceMatrix <- function( x, b.default=NULL, b.lower=-.6, b.upper=.6,
#'
#' @examples
#' g <- dagitty("graph{ a <-> x -> b ; c -- x <- d }")
#' # Includes "x"
#' descendants(g,"x")
#' # Does not include "x"
#' descendants(g,"x",TRUE)
#' parents(g,"x")
#' spouses(g,"x")
#'
NULL

#' @rdname AncestralRelations
#' @export
descendants <- function( x, v ){
.kins( x, v, "descendants" )
descendants <- function( x, v, proper=FALSE ){
r <- .kins( x, v, "descendants" )
if( proper ){
setdiff( r, v )
} else {
r
}
}

#' @rdname AncestralRelations
#' @export
ancestors <- function( x, v ){
.kins( x, v, "ancestors" )
ancestors <- function( x, v, proper=FALSE ){
r <- .kins( x, v, "ancestors" )
if( proper ){
setdiff( r, v )
} else {
r
}
}

#' @rdname AncestralRelations
Expand Down
17 changes: 13 additions & 4 deletions r/inst/js/dagitty-alg.js
Original file line number Diff line number Diff line change
Expand Up @@ -4536,7 +4536,7 @@ var GraphTransformer = {
}
})
})

// Delete all vertices that have not been marked for retention
if( opts.direct ){
_.each( intermediates_after_source, function(v){ retain[v.id] = true } )
Expand All @@ -4546,7 +4546,7 @@ var GraphTransformer = {
g_chain.deleteVertex(v)
}
} )

// Restore original edge types
var edges_to_replace = []
_.each( g_chain.edges, function(e){
Expand All @@ -4562,7 +4562,8 @@ var GraphTransformer = {
g_chain.addEdge( e.v2.id, e.v1.id, Graph.Edgetype.Directed )
}
} )



// Replace dummy nodes from canonical graph with original nodess
var Lids = _.pluck(g_canon.L,"id"), Sids = _.pluck(g_canon.S,"id")
L=[], S=[]
Expand All @@ -4577,17 +4578,25 @@ var GraphTransformer = {

// For direct effects, add causal paths between mediators
if( opts.direct ){
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources() ),
_.each( Z, Graph.Vertex.markAsVisited )
var gind = this.inducedSubgraph( g, _.intersection( g.descendantsOf( g.getSources(), preserve_previous_visited_information ),
g.ancestorsOf( g.getTargets() ) ) )
_.each( gind.edges, function(e){
if( e.directed == Graph.Edgetype.Directed && !(
(gind.isSource(e.v1)||gind.isTarget(e.v1)) && (gind.isSource(e.v2)||gind.isTarget(e.v2))) ){
if( !g_chain.getVertex( e.v1.id ) ){
g_chain.addVertex( e.v1.id )
}
if( !g_chain.getVertex( e.v2.id ) ){
g_chain.addVertex( e.v2.id )
}
g_chain.addEdge( e.v1.id, e.v2.id, Graph.Edgetype.Directed )
}
})
}
g = GraphTransformer.decanonicalize( g_chain, L, S )
g.setType( in_type )

return g
}, // end of activeBiasGraph

Expand Down
13 changes: 10 additions & 3 deletions r/man/AncestralRelations.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions r/tests/testthat/testBasics.R
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,9 @@ test_that("children and parents of nothing", {
expect_equal( length(parents("a->b",c())), 0 )
} )

test_that("proper and non-proper ancestors ",{
expect_equal( "x" %in% ancestors(dagitty("graph{a <-> x -> b ; c -- x <- d}"), "x"), TRUE )
expect_equal( "x" %in% ancestors(dagitty("graph{a <-> x -> b ; c -- x <- d}"), "x",TRUE), FALSE )
expect_equal( "x" %in% descendants(dagitty("graph{a <-> x -> b ; c -- x <- d}"), "x"), TRUE )
expect_equal( "x" %in% descendants(dagitty("graph{a <-> x -> b ; c -- x <- d}"), "x",TRUE), FALSE )
} )
8 changes: 7 additions & 1 deletion test/test/biasing-paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,17 @@ assert.equal((function(){
return $es(GraphTransformer.activeBiasGraph(g))
})(), "" )


assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->m->y z->{x y}"), { X:["x"] , Y:["y"] } ).edges.length, 2 )

assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->m->y"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 2 )

assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->m->y"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 2 )

assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->m->y"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 2 )
assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->{m[a]}->y"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 0 )
assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->{{m[a]}->y}<-z"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 3 )
assert.equal( GraphTransformer.activeBiasGraph( new Graph("x->{{m[a]}->y}<-{z[a]}"), {direct : true, X:["x"], Y:["y"] } ).edges.length, 0 )


});

0 comments on commit ca4ec74

Please sign in to comment.