again, we have to load some libraries
library(pMineR,quietly = TRUE)
library(kableExtra,quietly = TRUE)
library(DiagrammeR,quietly = TRUE)
library(survival,quietly = TRUE)
Let’s begin by loading a PWL diagram:
objCC <- confCheck_easy(verbose.mode = FALSE)
objCC$loadWorkFlow(WF.fileName = "./XML-PWL/four.overview.xml")
That’s the content of the XML-PWL file:
<xml>
<workflow>
<node name='Suspects'></node>
<node name='firstContact'></node>
<node name='imaging'></node>
<node name='patology'></node>
<node name='surgery'></node>
<node name='chemotherapy'></node>
<node name='radiotherapy'></node>
<node name='followup'></node>
<node name='dead' type='END'></node>
<node name='alive'></node>
<node name='pre Treatment'></node>
<node name='Treatment'></node>
<trigger name='t_Suspects'>
<condition>'BEGIN' %in% $st.ACTIVE$</condition>
<set>'Suspects'</set>
<set>'pre Treatment'</set>
<set>'alive'</set>
<unset>'BEGIN'</unset>
</trigger>
<trigger name='t_firstContact'>
<condition>'Suspects' %in% $st.ACTIVE$ AND $ev.NOW$=='MedicalVisit'</condition>
<set>'firstContact'</set>
<unset>'Suspects'</unset>
</trigger>
<trigger name='t_MedicalExamination'>
<condition>'Suspects' %in% $st.ACTIVE$ AND $ev.NOW$=='Biopsy'</condition>
<set>'patology'</set>
<unset>'Suspects'</unset>
<unset>'firstContact'</unset>
</trigger>
<trigger name='t_surgery'>
<condition>'patology' %in% $st.ACTIVE$ AND ($ev.NOW$=='total resection' OR $ev.NOW$=='partial resection')</condition>
<set>'surgery'</set>
<set>'Treatment'</set>
<unset>'pre Treatment'</unset>
<unset>'patology'</unset>
</trigger>
<trigger name='t_radiotherapy'>
<condition>'Treatment' %in% $st.ACTIVE$ AND $ev.NOW$=='radiotherapy' </condition>
<set>'radiotherapy'</set>
<unset>'surgery'</unset>
</trigger>
<trigger name='t_chemotherapy'>
<condition>'Treatment' %in% $st.ACTIVE$ AND $ev.NOW$=='chemotherapy'</condition>
<set>'chemotherapy'</set>
<unset>'surgery'</unset>
</trigger>
<trigger name='t_followup'>
<condition>('surgery' %in% $st.ACTIVE$ OR 'radiotherapy' %in% $st.ACTIVE$ OR 'chemotherapy' %in% $st.ACTIVE$) AND $ev.NOW$=='MedicalVisit'</condition>
<set>'followup'</set>
<unset>'surgery'</unset>
<unset>'Treatment'</unset>
<unset>'chemotherapy'</unset>
<unset>'radiotherapy'</unset>
</trigger>
<trigger name='t_death'>
<condition>$ev.NOW$=='death' AND !('BEGIN' %in% $st.ACTIVE$)</condition>
<set>'dead'</set>
<unset>'alive'</unset>
</trigger>
</workflow>
</xml>
and it has this graph:
grViz(objCC$plot(giveBack.grVizScript = T))
Now we can load an Event Log, as usual, with:
objDL = dataLoader(verbose.mode = F)
objDL$load.csv(nomeFile = "./csv/four.generated.csv", IDName = "ID", EVENTName = "Event", dateColumnName = "Date",sep = ";", format.column.date = "%Y-%m-%d")
Now we can load the Event Log into the PWL diagram :
objCC$loadDataset(dataList = objDL$getData())
and we can let it flows through the diagram with a replay:
objCC$replay()
In this tutorial we can see a graphical way to see the result of the computation:
objCC$plot.replay.result(whatToCount = "terminations", kindOfNumber = "absolute")
It sounds. We have 100 patients, so:
as expected.
We can also take a look on transitions, just to have an idea about how often the states have been activated during the computation (non only as final states)
objCC$plot.replay.result( kindOfNumber = "absolute")
Again: It sounds. We have 100 patients, so:
Another point of view is by a matrix we have already seen.
lst.res <- objCC$get.list.replay.result()
This list contains many keys.
list.fired.trigger shows, for each patient, which triggers he fired
list.final.states shows the final active states of each patient
termination.END.states for each patient says if he reached a final state or not
list.computation.matrix$stati.timeline shows when each node has been set or unset, for each patient, also providing the time of the set/unset event
list.computation.matrix$trigger is a matrix containing who fired what :
lst.res$list.computation.matrix$trigger[1:20,] %>%
kbl() %>%
kable_minimal()
t_Suspects | t_firstContact | t_MedicalExamination | t_surgery | t_radiotherapy | t_chemotherapy | t_followup | t_death | |
---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
10 | 1 | 0 | 1 | 1 | 0 | 3 | 1 | 1 |
100 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
11 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
12 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
13 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
14 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
15 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
16 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
17 | 1 | 0 | 1 | 1 | 2 | 3 | 1 | 1 |
18 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
19 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
2 | 1 | 0 | 1 | 1 | 11 | 4 | 1 | 1 |
20 | 1 | 0 | 1 | 1 | 7 | 2 | 1 | 1 |
21 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
22 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
23 | 1 | 0 | 1 | 1 | 11 | 0 | 0 | 1 |
24 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
25 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
26 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
lst.res$list.computation.matrix$stati.transizione[1:20,] %>%
kbl() %>%
kable_minimal()
Suspects | firstContact | imaging | patology | surgery | chemotherapy | radiotherapy | followup | dead | alive | pre Treatment | Treatment | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
10 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
100 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
11 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
12 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
13 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
14 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
15 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
16 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
17 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
18 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
19 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
20 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
21 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
22 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
23 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
24 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
25 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
26 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
lst.res$list.computation.matrix$stati.finali[1:20,] %>%
kbl() %>%
kable_minimal()
Suspects | firstContact | imaging | patology | surgery | chemotherapy | radiotherapy | followup | dead | alive | pre Treatment | Treatment | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
100 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
11 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
12 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
14 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
16 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
17 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
18 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
19 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
21 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
22 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
23 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
24 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
26 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
We are interested in analyzing the performances (OS) of the patients treated with ‘surgery’ vs ‘surgery+radiochemo’. To do that, we have to understand which patients flow thought the different brances of the graph. For example, to have the patient treated exclusively with surgery (and now dead), we can use:
path.1 <- objCC$KaplanMeier(fromState = "Suspects",toState = "dead",passingThrough = c("surgery"),passingNotThrough = c("chemotherapy","radiotherapy"),UM = "days")
Now, path.1 is a list containing:
To extract the patient treated with surgery+radioChemo:
path.2 <- objCC$KaplanMeier(fromState = "Suspects",toState = "dead",passingThrough = c("surgery","chemotherapy","radiotherapy"),UM = "days")
To make a logrank test we can use the R functions of the package survivail or we can easily use the method:
yak <- objCC$logRankTest(KM1 = path.1,KM2 = path.2)
Again, yak is a list with two elements:
As expected, we have a significant difference:
yak$survdiff
## Call:
## survdiff(formula = Surv(time, outcome) ~ KM, data = new.df)
##
## N Observed Expected (O-E)^2/E (O-E)^2/V
## KM=KM1 54 54 46.2 1.31 5.1
## KM=KM2 10 10 17.8 3.41 5.1
##
## Chisq= 5.1 on 1 degrees of freedom, p= 0.02
To hae a nice view:
plot(yak$survfit,conf.int = T,col=c("red","blue"), xlab="days",ylab="population (%)", main="Surgery vs Surgery+RadioChemo")