Installing

For the package pm4py — the R interface between bupaR and the PM4Py python library (http://pm4py.org/) — you also need to install Python. After installing pm4py, the corresponding PM4Py python library can be installed as follows:

pm4py::install_pm4py()

See the ‘reticulate’ documentation for more information on the available options or how to specify an existing Python environment: https://rstudio.github.io/reticulate/

Example

library(pm4py)
library(bupaR)

# As Inductive Miner of PM4PY is not life-cycle aware, keep only `complete` events:
patients_completes <- patients[patients$registration_type == "complete", ]

# Discovery with Inductive Miner
pn <- discovery_inductive(patients_completes)

# This results in an auto-converted bupaR Petri net and markings
str(pn)
## List of 3
##  $ petrinet       :List of 4
##   ..$ places     :'data.frame':  8 obs. of  1 variable:
##   .. ..$ id: chr [1:8] "p_5" "sink" "p_6" "p_7" ...
##   ..$ transitions:'data.frame':  10 obs. of  2 variables:
##   .. ..$ id   : chr [1:10] "Blood test" "MRI SCAN" "skip_3" "Check-out" ...
##   .. ..$ label: chr [1:10] "Blood test" "MRI SCAN" NA "Check-out" ...
##   ..$ flows      :'data.frame':  20 obs. of  2 variables:
##   .. ..$ from: chr [1:20] "MRI SCAN" "p_4" "Check-out" "p_3" ...
##   .. ..$ to  : chr [1:20] "p_6" "Blood test" "sink" "Triage and Assessment" ...
##   ..$ marking    : chr "source"
##   ..- attr(*, "class")= chr "petrinet"
##  $ initial_marking: chr "source"
##  $ final_marking  : chr "sink"
class(pn$petrinet)
## [1] "petrinet"
# Render with bupaR
render_PN(pn$petrinet)
# Render with  PM4PY and DiagrammeR
library(DiagrammeR)
viz <- reticulate::import("pm4py.visualization.petrinet")

# Convert back to Python
py_pn <- r_to_py(pn$petrinet)
class(py_pn)
## [1] "pm4py.objects.petri.petrinet.PetriNet"
## [2] "python.builtin.object"
# Render to DOT with PMP4Y
dot <- viz$factory$apply(py_pn)$source
grViz(diagram = dot)
# Compute alignment
alignment <- conformance_alignment(patients_completes, pn$petrinet, pn$initial_marking, pn$final_marking)

# # Alignment is returned in long format as data frame
head(alignment)
##   case_id                    log_id              model_id
## 1       1          t_Registration_0          Registration
## 2       1 t_Triage and Assessment_1 Triage and Assessment
## 3       1            t_Blood test_2            Blood test
## 4       1              t_MRI SCAN_3              MRI SCAN
## 5       1                        >>                skip_3
## 6       1       t_Discuss Results_4       Discuss Results
##               log_label           model_label cost visited_states
## 1          Registration          Registration    1              8
## 2 Triage and Assessment Triage and Assessment    1              8
## 3            Blood test            Blood test    1              8
## 4              MRI SCAN              MRI SCAN    1              8
## 5                    >>                  <NA>    1              8
## 6       Discuss Results       Discuss Results    1              8
##   queued_states traversed_arcs fitness
## 1            22             23       1
## 2            22             23       1
## 3            22             23       1
## 4            22             23       1
## 5            22             23       1
## 6            22             23       1
# Evaluate model quality
quality <- evaluation_all(patients_completes, pn$petrinet, pn$initial_marking, pn$final_marking)

quality
## $fitness
## $fitness$perc_fit_traces
## [1] 100
## 
## $fitness$average_trace_fitness
## [1] 0.99805
## 
## $fitness$log_fitness
## [1] 0.9987581
## 
## 
## $precision
## [1] 0.6147411
## 
## $generalization
## [1] 0.9439686
## 
## $simplicity
## [1] 0.5555556
## 
## $metricsAverageWeight
## [1] 0.7782559