simcausal (version 0.2.0)

add.action: Define and Add Actions (Interventions)

Description

Define and add new action (intervention) to the existing DAG object. Use either syntax DAG + action(name = ,nodes = ) or add.action((DAG = ,name = ,nodes = ). Both give identical results, see the examples in the vignette and below for details.

Usage

add.action(DAG, name, nodes, ..., attr = list())

action(...)

Arguments

DAG
DAG object
name
Unique name of the action
nodes
A list of node objects that defines the action on the DAG (replaces the distributions of the corresponding nodes in DAG)
...
Additional named attributes defining / indexing the action
attr
Additional named attributes defining / indexing the action

Value

  • A modified DAG object with the added action

Details

In addition to the action name and list of action nodes, both of these functions accept arbitrary named attributes (as additional arguments which must be given a name). This additional attributes can be used to simplify specification of dynamic regimes (actions that depend on the past observed covariates).

The formula of the intervention node is allowed to contain undefined variables, as long as those are later defined as a named argument to action.

In Example 2 below, node("A",..., mean = ifelse(W1 >= theta, 1, 0)), defines the mean of the node "A" as a function of some undefined variable theta, setting A to 1 if the baseline node W1 is above or equal to theta and 0 vice versa. One specifies actual values of theta while defining a new action, possible creating a series of actions, each indexed by a different value of theta. A new action can be defined with D<-D+action("A1th0.1", nodes=actN, theta=0.1).

Note that any name can be used in place of theta. This attribute variable can appear anywhere inside the node distribution formula. Finally, the attribute variable can also be time varying and, just like with DAG nodes, can be indexed by square bracket notation, theta[t]. See Example 3 for defining time-varying attributes.

Examples

Run this code
#---------------------------------------------------------------------------------------
# EXAMPLE 1: Showing two equivalent ways of defining an action for a simple DAG
#---------------------------------------------------------------------------------------

D <- DAG.empty()
D <- D + node(name="W1", distr="rbern", prob=plogis(-0.5))
D <- D + node(name="W2", distr="rbern", prob=plogis(-0.5 + 0.5*W1))
D <- D + node(name="A", distr="rbern", prob=plogis(-0.5 + 0.5*W1+ 0.5*W2))
D <- set.DAG(D)

# Syntax '+ action': define two actions, intervening on node "A", imputing order
D <- D + action("A0", nodes=node("A", distr="rbern", prob=0))
D <- D + action("A1", nodes=node("A", distr="rbern", prob=1))

# Equivalent syntax 'add.action': define two actions, intervening on node "A"
D <- add.action(D, "A0", nodes=node("A", distr="rbern", prob=0))
D <- add.action(D, "A1", nodes=node("A", distr="rbern", prob=1))

#---------------------------------------------------------------------------------------
# EXAMPLE 2: Adding named attributes that define (index) the action.
# Define intervention on A that is conditional on W1 crossing some threshold theta
#---------------------------------------------------------------------------------------

# Redefining node W1 as uniform [0,1]
D <- DAG.empty()
D <- D + node(name="W1", distr="runif", min=0, max=1)
D <- D + node(name="W2", distr="rbern", prob=plogis(-0.5 + 0.5*W1))
D <- D + node(name="A", distr="rbern", prob=plogis(-0.5 + 0.5*W1+ 0.5*W2))
D <- set.DAG(D)

# Define a node that is indexed by unknown variable theta
actN<-node("A",distr="rbern",prob=ifelse(W1 >= theta,1,0))
# Define 3 actions for theta=0.1, 0.5, 0.9
D <- D + action("A1th0.1", nodes=actN, theta=0.1)
D <- D + action("A1th0.5", nodes=actN, theta=0.5)
D <- D + action("A1th0.9", nodes=actN, theta=0.9)

# Simulate 50 observations per each action above
simfull(A(D), n=50)

#---------------------------------------------------------------------------------------
# EXAMPLE 3: Time-varying action attributes for longitudinal DAG
#---------------------------------------------------------------------------------------
# Define longitudinal data structure over 6 time-points t=(0:5) with survival outcome "Y"
t_end <- 5
D <- DAG.empty()
D <- D + node("L2", t=0, distr="rbern", prob=0.05)
D <- D + node("L1", t=0, distr="rbern", prob=ifelse(L2[0]==1,0.5,0.1))
D <- D + node("A1", t=0, distr="rbern", prob=ifelse(L1[0]==1, 0.5, 0.1))
D <- D + node("Y",  t=0, distr="rbern", 
                prob=plogis(-6.5 + L1[0] + 4*L2[0] + 0.05*I(L2[0]==0)), EFU=TRUE)
D <- D + node("L2", t=1:t_end, distr="rbern", prob=ifelse(A1[t-1]==1, 0.1, 0.9))
D <- D + node("A1", t=1:t_end, distr="rbern", 
              prob=ifelse(A1[t-1]==1, 1, ifelse(L1[0]==1 & L2[0]==0, 0.3, 0.5)))
D <- D + node("Y",  t=1:t_end, distr="rbern", prob=plogis(-6.5+L1[0]+4*L2[t]), EFU=TRUE)
D <- set.DAG(D)

#---------------------------------------------------------------------------------------
# Dynamic actions indexed by constant value of parameter theta={0,1})
#---------------------------------------------------------------------------------------
# Define time-varying node A1: sets A1 to 1 if L2 at t is >= theta
actN_A1 <- node("A1",t=0:t_end, distr="rbern", prob=ifelse(L2[t] >= theta,1,0))

# Define two actions, indexed by fixed values of theta={0,1}
D_act <- D + action("A1_th0", nodes=actN_A1, theta=0)
D_act <- D_act + action("A1_th1", nodes=actN_A1, theta=1)

# Simulate 50 observations for per each action above
simfull(A(D_act), n=50)

#---------------------------------------------------------------------------------------
# Dynamic actions indexed by time-varying parameter theta[t]
#---------------------------------------------------------------------------------------
# This defines an action node with threshold theta varying in time (note syntax theta[t])
actN_A1 <- node("A1",t=0:t_end, distr="rbern", prob=ifelse(L2[t] >= theta[t],1,0))

# Now define 3 actions that are indexed by various values of theta over time
D_act <- D + action("A1_th_const0", nodes=actN_A1, theta=rep(0,(t_end+1)))
D_act <- D_act + action("A1_th_var1", nodes=actN_A1, theta=c(0,0,0,1,1,1))
D_act <- D_act + action("A1_th_var2", nodes=actN_A1, theta=c(0,1,1,1,1,1))

# Simulate 50 observations for per each action above
simfull(A(D_act), n=50)

Run the code above in your browser using DataCamp Workspace