1 first of all

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))
boxes_and_circles BEGIN BEGIN t_Suspects t_Suspects BEGIN->t_Suspects dead dead Suspects Suspects t_firstContact t_firstContact Suspects->t_firstContact t_MedicalExamination t_MedicalExamination Suspects->t_MedicalExamination pre Treatment pre Treatment t_surgery t_surgery pre Treatment->t_surgery alive alive t_death t_death alive->t_death firstContact firstContact firstContact->t_MedicalExamination patology patology patology->t_surgery surgery surgery t_radiotherapy t_radiotherapy surgery->t_radiotherapy t_chemotherapy t_chemotherapy surgery->t_chemotherapy t_followup t_followup surgery->t_followup Treatment Treatment Treatment->t_followup radiotherapy radiotherapy radiotherapy->t_followup chemotherapy chemotherapy chemotherapy->t_followup followup followup t_Suspects->Suspects t_Suspects->pre Treatment t_Suspects->alive t_firstContact->firstContact t_MedicalExamination->patology t_surgery->surgery t_surgery->Treatment t_radiotherapy->radiotherapy t_chemotherapy->chemotherapy t_followup->followup t_death->dead

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()

2 Getting the results

In this tutorial we can see a graphical way to see the result of the computation:

objCC$plot.replay.result(whatToCount = "terminations", kindOfNumber = "absolute")
boxes_and_circles BEGIN BEGIN # 100 t_Suspects t_Suspects # 100 BEGIN->t_Suspects dead dead Suspects Suspects # 13 t_MedicalExamination t_MedicalExamination # 87 Suspects->t_MedicalExamination t_firstContact t_firstContact Suspects->t_firstContact pre Treatment pre Treatment # 18 t_surgery t_surgery # 82 pre Treatment->t_surgery alive alive # 2 t_death t_death # 98 alive->t_death firstContact firstContact # 0 firstContact->t_MedicalExamination patology patology # 5 patology->t_surgery surgery surgery # 36 t_radiotherapy t_radiotherapy # 17 surgery->t_radiotherapy t_chemotherapy t_chemotherapy # 19 surgery->t_chemotherapy t_followup t_followup # 43 surgery->t_followup Treatment Treatment # 39 Treatment->t_followup radiotherapy radiotherapy # 1 radiotherapy->t_followup chemotherapy chemotherapy # 2 chemotherapy->t_followup followup followup # 43 t_Suspects->Suspects t_Suspects->pre Treatment t_Suspects->alive t_MedicalExamination->patology t_surgery->surgery t_surgery->Treatment t_radiotherapy->radiotherapy t_chemotherapy->chemotherapy t_followup->followup t_death->dead t_firstContact->firstContact

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")
boxes_and_circles BEGIN BEGIN # 100 t_Suspects t_Suspects # 100 BEGIN->t_Suspects dead dead Suspects Suspects # 100 t_MedicalExamination t_MedicalExamination # 87 Suspects->t_MedicalExamination t_firstContact t_firstContact Suspects->t_firstContact pre Treatment pre Treatment # 100 t_surgery t_surgery # 82 pre Treatment->t_surgery alive alive # 100 t_death t_death # 98 alive->t_death firstContact firstContact # 0 firstContact->t_MedicalExamination patology patology # 87 patology->t_surgery surgery surgery # 82 t_radiotherapy t_radiotherapy # 17 surgery->t_radiotherapy t_chemotherapy t_chemotherapy # 19 surgery->t_chemotherapy t_followup t_followup # 43 surgery->t_followup Treatment Treatment # 82 Treatment->t_followup radiotherapy radiotherapy # 17 radiotherapy->t_followup chemotherapy chemotherapy # 19 chemotherapy->t_followup followup followup # 43 t_Suspects->Suspects t_Suspects->pre Treatment t_Suspects->alive t_MedicalExamination->patology t_surgery->surgery t_surgery->Treatment t_radiotherapy->radiotherapy t_chemotherapy->chemotherapy t_followup->followup t_death->dead t_firstContact->firstContact

Again: It sounds. We have 100 patients, so:

3 More results

Another point of view is by a matrix we have already seen.

lst.res <- objCC$get.list.replay.result()

This list contains many keys.

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

4 It’s time to survival analysis

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")