Example: Inferred binary causal graph from simulation

In the first step, we generate a simulation dataset as an input.

seedN<-2022

n<-200 # 200 individuals
d<-10 # 10 variables
mat<-matrix(nrow=n,ncol=d) # the input of framework

#Simulate binary data from binomial distribution where the probability of value being 1 is 0.5.
for(i in seq(n))
{
  set.seed(seedN+i)
  mat[i,] <- rbinom(n=d, size=1, prob=0.5)
}

mat[,1]<-mat[,2] | mat[,3]  # 1 causes by 2 and 3
mat[,4] <-mat[,2] | mat[,5] # 4 causses by 2 and 5
mat[,6] <- mat[,1] | mat[,4] # 6 causes by 1 and 4

We use the following function to infer whether X causes Y.

# Run the function
library(BiCausality)
resC<-BiCausality::CausalGraphInferMainFunc(mat = mat,CausalThs=0.1, nboot =50, IndpThs=0.05)
[1] "Inferring dependent graph"
[1] "Removing confounder(s)"
[1] "Inferring causal graph"

The result of the ajacency matrix of the directed causal graph is below:

resC$CausalGRes$Ehat
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    0    1    0    0    0     0
 [2,]    1    0    0    1    0    0    0    0    0     0
 [3,]    1    0    0    0    0    0    0    0    0     0
 [4,]    0    0    0    0    0    1    0    0    0     0
 [5,]    0    0    0    1    0    0    0    0    0     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     0
 [8,]    0    0    0    0    0    0    0    0    0     0
 [9,]    0    0    0    0    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

The value in the element EValHat[i,j] represents that i causes j if the value is not zero. For example, EValHat[2,1] = 1 implies node 2 causes node 1, which is correct since node 1 have nodes 2 and 3 as causal nodes.

The directed causal graph also can be plot using the code below.

library(igraph)

Attaching package: ‘igraph’

The following objects are masked from ‘package:stats’:

    decompose, spectrum

The following object is masked from ‘package:base’:

    union
net <- graph_from_adjacency_matrix(resC$CausalGRes$Ehat ,weighted = NULL)
plot(net, edge.arrow.size = 0.3, vertex.size =20 , vertex.color = '#D4C8E9',layout=layout_with_kk)

For the causal relation of variables 2 and 1, we can use the command below to see further information.

**Note that the odd difference between X and Y denoted oddDiff(X,Y) is define as |P (X = 1, Y = 1) P (X = 0, Y = 0) −P (X = 0, Y = 1) P (X = 1, Y = 0)|. If X is directly proportional to Y, then oddDiff(X,Y) is close to 1. If X is inverse of Y, then oddDiff(X,Y) is close to -1. If X and Y have no association, then oddDiff(X,Y) is close to zero.

resC$CausalGRes$causalInfo[['2,1']]
$CDirConfValInv
 2.5% 97.5% 
    1     1 

$CDirConfInv
     2.5%     97.5% 
0.3152526 0.4386415 

$CDirmean
[1] 0.371347

$testRes2

    Wilcoxon signed rank test with continuity correction

data:  abs(bCausalDirDist)
V = 1275, p-value = 3.893e-10
alternative hypothesis: true location is greater than 0.1


$testRes1

    Wilcoxon signed rank test with continuity correction

data:  abs(bSignDist)
V = 1275, p-value = 3.893e-10
alternative hypothesis: true location is greater than 0.05


$sign
[1] 1

$SignConfInv
     2.5%     97.5% 
0.0868440 0.1287719 

$Signmean
[1] 0.1095157

Below are the details of result explanation.

#This value represents the 95th percentile confidence interval of P(Y=1|X=1). 
$CDirConfValInv
 2.5% 97.5% 
    1     1 
#This value represents the 95th percentile confidence interval of |P(Y=1|X=1) - P(X=1|Y=1)|.
$CDirConfInv
     2.5%     97.5% 
0.3217322 0.4534494 

#This value represents the mean of |P(Y=1|X=1) - P(X=1|Y=1)|.
$CDirmean
[1] 0.3787904

#The test that has the null hypothesis that |P(Y=1|X=1) - P(X=1|Y=1)| below
#or equal the argument of parameter "CausalThs" and the alternative hypothesis
#is that |P(Y=1|X=1) - P(X=1|Y=1)| is greater than "CausalThs".
$testRes2

    Wilcoxon signed rank test with continuity correction

data:  abs(bCausalDirDist)
V = 1275, p-value = 3.893e-10
alternative hypothesis: true location is greater than 0.1


#The test that has the null hypothesis that |oddDiff(X,Y)| below 
#or equal the argument of parameter "IndpThs" and the alternative hypothesis is
#that |oddDiff(X,Y)| is greater than "IndpThs". 
$testRes1

    Wilcoxon signed rank test with continuity correction

data:  abs(bSignDist)
V = 1275, p-value = 3.894e-10
alternative hypothesis: true location is greater than 0.05

#If the test above rejects the null hypothesis with the significance threshold
#alpha (default alpha=0.05), then the value "sign=1", otherwise, it is zero.
$sign
[1] 1

#This value represents the 95th percentile confidence interval of oddDiff(X,Y)
$SignConfInv
      2.5%      97.5% 
0.08670325 0.13693900 

#This value represents the mean of oddDiff(X,Y)
$Signmean
[1] 0.1082242
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKRXhhbXBsZTogSW5mZXJyZWQgYmluYXJ5IGNhdXNhbCBncmFwaCBmcm9tIHNpbXVsYXRpb24KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJbiB0aGUgZmlyc3Qgc3RlcCwgd2UgZ2VuZXJhdGUgYSBzaW11bGF0aW9uIGRhdGFzZXQgYXMgYW4gaW5wdXQuCmBgYHtyfQpzZWVkTjwtMjAyMgoKbjwtMjAwICMgMjAwIGluZGl2aWR1YWxzCmQ8LTEwICMgMTAgdmFyaWFibGVzCm1hdDwtbWF0cml4KG5yb3c9bixuY29sPWQpICMgdGhlIGlucHV0IG9mIGZyYW1ld29yawoKI1NpbXVsYXRlIGJpbmFyeSBkYXRhIGZyb20gYmlub21pYWwgZGlzdHJpYnV0aW9uIHdoZXJlIHRoZSBwcm9iYWJpbGl0eSBvZiB2YWx1ZSBiZWluZyAxIGlzIDAuNS4KZm9yKGkgaW4gc2VxKG4pKQp7CiAgc2V0LnNlZWQoc2VlZE4raSkKICBtYXRbaSxdIDwtIHJiaW5vbShuPWQsIHNpemU9MSwgcHJvYj0wLjUpCn0KCm1hdFssMV08LW1hdFssMl0gfCBtYXRbLDNdICAjIDEgY2F1c2VzIGJ5IDIgYW5kIDMKbWF0Wyw0XSA8LW1hdFssMl0gfCBtYXRbLDVdICMgNCBjYXVzc2VzIGJ5IDIgYW5kIDUKbWF0Wyw2XSA8LSBtYXRbLDFdIHwgbWF0Wyw0XSAjIDYgY2F1c2VzIGJ5IDEgYW5kIDQKCmBgYAoKV2UgdXNlIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gdG8gaW5mZXIgd2hldGhlciBYIGNhdXNlcyBZLgpgYGAge3J9CiMgUnVuIHRoZSBmdW5jdGlvbgpsaWJyYXJ5KEJpQ2F1c2FsaXR5KQpyZXNDPC1CaUNhdXNhbGl0eTo6Q2F1c2FsR3JhcGhJbmZlck1haW5GdW5jKG1hdCA9IG1hdCxDYXVzYWxUaHM9MC4xLCBuYm9vdCA9NTAsIEluZHBUaHM9MC4wNSkKYGBgClRoZSByZXN1bHQgb2YgdGhlIGFqYWNlbmN5IG1hdHJpeCBvZiB0aGUgZGlyZWN0ZWQgY2F1c2FsIGdyYXBoIGlzIGJlbG93OgoKYGBge3J9CnJlc0MkQ2F1c2FsR1JlcyRFaGF0CmBgYApUaGUgdmFsdWUgaW4gdGhlIGVsZW1lbnQgRVZhbEhhdFtpLGpdIHJlcHJlc2VudHMgdGhhdCBpIGNhdXNlcyBqIGlmIHRoZSB2YWx1ZSBpcyBub3QgemVyby4gRm9yIGV4YW1wbGUsIEVWYWxIYXRbMiwxXSA9IDEgaW1wbGllcyBub2RlIDIgY2F1c2VzIG5vZGUgMSwgd2hpY2ggaXMgY29ycmVjdCBzaW5jZSBub2RlIDEgaGF2ZSBub2RlcyAyIGFuZCAzIGFzIGNhdXNhbCBub2Rlcy4KClRoZSBkaXJlY3RlZCBjYXVzYWwgZ3JhcGggYWxzbyBjYW4gYmUgcGxvdCB1c2luZyB0aGUgY29kZSBiZWxvdy4KYGBge3J9CmxpYnJhcnkoaWdyYXBoKQpuZXQgPC0gZ3JhcGhfZnJvbV9hZGphY2VuY3lfbWF0cml4KHJlc0MkQ2F1c2FsR1JlcyRFaGF0ICx3ZWlnaHRlZCA9IE5VTEwpCnBsb3QobmV0LCBlZGdlLmFycm93LnNpemUgPSAwLjMsIHZlcnRleC5zaXplID0yMCAsIHZlcnRleC5jb2xvciA9ICcjRDRDOEU5JyxsYXlvdXQ9bGF5b3V0X3dpdGhfa2spCmBgYAoKCkZvciB0aGUgY2F1c2FsIHJlbGF0aW9uIG9mIHZhcmlhYmxlcyAyIGFuZCAxLCB3ZSBjYW4gdXNlIHRoZSBjb21tYW5kIGJlbG93IHRvIHNlZSBmdXJ0aGVyIGluZm9ybWF0aW9uLgoKKipOb3RlIHRoYXQgdGhlIG9kZCBkaWZmZXJlbmNlIGJldHdlZW4gWCBhbmQgWSBkZW5vdGVkIG9kZERpZmYoWCxZKSBpcyBkZWZpbmUgYXMKfFAgKFggPSAxLCBZID0gMSkgUCAoWCA9IDAsIFkgPSAwKSDiiJJQIChYID0gMCwgWSA9IDEpIFAgKFggPSAxLCBZID0gMCl8LiAgSWYgWCBpcyBkaXJlY3RseSBwcm9wb3J0aW9uYWwgdG8gWSwgdGhlbiBvZGREaWZmKFgsWSkgaXMgY2xvc2UgdG8gMS4gSWYgWCBpcyBpbnZlcnNlIG9mIFksIHRoZW4gb2RkRGlmZihYLFkpIGlzIGNsb3NlIHRvIC0xLiBJZiBYIGFuZCBZIGhhdmUgbm8gYXNzb2NpYXRpb24sIHRoZW4gb2RkRGlmZihYLFkpIGlzIGNsb3NlIHRvIHplcm8uCgpgYGB7cn0KcmVzQyRDYXVzYWxHUmVzJGNhdXNhbEluZm9bWycyLDEnXV0KYGBgCkJlbG93IGFyZSB0aGUgZGV0YWlscyBvZiByZXN1bHQgZXhwbGFuYXRpb24uCgpgYGAKI1RoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgOTV0aCBwZXJjZW50aWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgUChZPTF8WD0xKS4gCiRDRGlyQ29uZlZhbEludgogMi41JSA5Ny41JSAKICAgIDEgICAgIDEgCiNUaGlzIHZhbHVlIHJlcHJlc2VudHMgdGhlIDk1dGggcGVyY2VudGlsZSBjb25maWRlbmNlIGludGVydmFsIG9mIHxQKFk9MXxYPTEpIC0gUChYPTF8WT0xKXwuCiRDRGlyQ29uZkludgogICAgIDIuNSUgICAgIDk3LjUlIAowLjMyMTczMjIgMC40NTM0NDk0IAoKI1RoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgbWVhbiBvZiB8UChZPTF8WD0xKSAtIFAoWD0xfFk9MSl8LgokQ0Rpcm1lYW4KWzFdIDAuMzc4NzkwNAoKI1RoZSB0ZXN0IHRoYXQgaGFzIHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB8UChZPTF8WD0xKSAtIFAoWD0xfFk9MSl8IGJlbG93CiNvciBlcXVhbCB0aGUgYXJndW1lbnQgb2YgcGFyYW1ldGVyICJDYXVzYWxUaHMiIGFuZCB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcwojaXMgdGhhdCB8UChZPTF8WD0xKSAtIFAoWD0xfFk9MSl8IGlzIGdyZWF0ZXIgdGhhbiAiQ2F1c2FsVGhzIi4KJHRlc3RSZXMyCgoJV2lsY294b24gc2lnbmVkIHJhbmsgdGVzdCB3aXRoIGNvbnRpbnVpdHkgY29ycmVjdGlvbgoKZGF0YTogIGFicyhiQ2F1c2FsRGlyRGlzdCkKViA9IDEyNzUsIHAtdmFsdWUgPSAzLjg5M2UtMTAKYWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogdHJ1ZSBsb2NhdGlvbiBpcyBncmVhdGVyIHRoYW4gMC4xCgoKI1RoZSB0ZXN0IHRoYXQgaGFzIHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB8b2RkRGlmZihYLFkpfCBiZWxvdyAKI29yIGVxdWFsIHRoZSBhcmd1bWVudCBvZiBwYXJhbWV0ZXIgIkluZHBUaHMiIGFuZCB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyBpcwojdGhhdCB8b2RkRGlmZihYLFkpfCBpcyBncmVhdGVyIHRoYW4gIkluZHBUaHMiLiAKJHRlc3RSZXMxCgoJV2lsY294b24gc2lnbmVkIHJhbmsgdGVzdCB3aXRoIGNvbnRpbnVpdHkgY29ycmVjdGlvbgoKZGF0YTogIGFicyhiU2lnbkRpc3QpClYgPSAxMjc1LCBwLXZhbHVlID0gMy44OTRlLTEwCmFsdGVybmF0aXZlIGh5cG90aGVzaXM6IHRydWUgbG9jYXRpb24gaXMgZ3JlYXRlciB0aGFuIDAuMDUKCiNJZiB0aGUgdGVzdCBhYm92ZSByZWplY3RzIHRoZSBudWxsIGh5cG90aGVzaXMgd2l0aCB0aGUgc2lnbmlmaWNhbmNlIHRocmVzaG9sZAojYWxwaGEgKGRlZmF1bHQgYWxwaGE9MC4wNSksIHRoZW4gdGhlIHZhbHVlICJzaWduPTEiLCBvdGhlcndpc2UsIGl0IGlzIHplcm8uCiRzaWduClsxXSAxCgojVGhpcyB2YWx1ZSByZXByZXNlbnRzIHRoZSA5NXRoIHBlcmNlbnRpbGUgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiBvZGREaWZmKFgsWSkKJFNpZ25Db25mSW52CiAgICAgIDIuNSUgICAgICA5Ny41JSAKMC4wODY3MDMyNSAwLjEzNjkzOTAwIAoKI1RoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgbWVhbiBvZiBvZGREaWZmKFgsWSkKJFNpZ25tZWFuClsxXSAwLjEwODIyNDIKYGBgCg==