Skip to main content

Patient-report shiny app


Please consult 'using shiny apps for reporting' for more background information.

The patient-report shiny app serves as a patient data reporting tool for the Mental Health Information Reporting Assisitant (MHIRA).


This documenation refers to this repository

What is the patient report?

Click here for an example

How to make the patient report work with MHIRA

Installing the app to work with MHIRA:

You can clone the app to the folder inside the shiny server using

git clone

Updating the app

For updating the shiny app, navigate inside the folder containing the app and use

git pull

Adding algorithms for sales and cutoffs for the questionnairs

For the patient-report to work you will need to provide information on how to calculate scales and on the cutoffs for these scales.

For example the questionnaire PHQ-9 which evaluates depressive symtoms presents with a "Total Score" which is the sum of the scores for its 9 items. PHQ-9 also has cutoff points: It comprises five categories, where a cut-off point of 0–4 indicates no depressive symptoms, 5–9 mild depressive symptoms, 10–14 moderate depressive symptoms, 15–19 moderately-severe depressive symptoms, and 20–27 severe depressive symptoms.

We need to provide this information to the patient-report: To this aim, files containing this information can be uploaded together whith the questionniares under the 'script tab' in the 'questionnaires' menu (accessible from the navigation bar).



Any text based file can be uploaded ('.txt', '.csv', '.R', '.py'). Please make sure the files are encoded in 'UTF-8'. The encoding can be selected in the 'save as' menu in excel and many text editors. The extension (e.g. '.txt') of the file does not matter.


The patient report shiny app needs a formula to calculte the scales of the questionnaire. These can be uploaded in form of a '.csv' table.

TotalScoreq1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q90281
  • ScaleName: The name of the scale.
  • Formula: R code to calculate the scale. The names of the objects (q1,q2,...) come from the names selected in the xlsform you used to create the questionnaire.
  • scaleMin: Sets the lower limit in the plot.
  • scalesMax: Sets the upper limit in the plot.
  • mean: mean of healthy population, currently not used.
  • sd: standard deviation of normal population, currently not used.
  • plotGroup: Should the scale be printed in the plot. Empty values or zeros are not printed. Providing different values >= 0 will result in a plot with multiple facets which have their own sale range. Multiple scales with the same value >= 0 will result in these scales printed in the same facet.

When uploading these files, the file name does not matter. However the name of the scripts input in the MHIRA form needs to be 'scales_table'.


CSV files containing cutoffs can be uploaded in the following format.

TotalScore05noneFALSE1The level of depression was none.
TotalScore510mildFALSE1The level of depression was mild.Please consider further clincal interviews to find out if help regarding depression is required.
TotalScore1015moderateFALSE1The level of depression was moderate.Please consider further clincal interviews to find out if help regarding depression is required.
TotalScore1520moderately severeFALSE1The level of depression was moderately severe.
TotalScore2028severeFALSE1The level of depression was severe.Discuss the case with a psychiatrist at your department. Medication might be helpful.
Suicidality01not at allFALSE2The patient was not at all suicidal.
Suicidality12several daysTRUE2The patient suicidal on several days.Make sure the patient does't harm himself.
Suicidality23more than half the daysTRUE2The patient was suicidal on more than half of the days.Make sure the patient does't harm himself.
Suicidality34nearly every dayTRUE2The patient suicidal nearly every day.Please consider hospitalisation to keep the patient safe.


  • scale: Needs to correspond to the scaleName in scales_table. This is a common source of errors
  • low_cut: Included lower cutoff for a certain level. The upper bound is not inculded.
  • high_cut: Included higher cutoff for the level. The upper bound is not included except for the highest level.
  • level: severity level of these cutoffs. Will be used in the plot legend.
  • text_order: The order in which the scales are represented. Will allow to concatenate the interpretations and recommendations.
  • Interpretation: Text bocks associated to a certain level.
  • Recommendatin: Text bocks associated to a certain level.

The cutoff script needs to be named 'cutoffs' in the MHIRA form.


Sometimes calculating the scales is more complex. In these cases, a table might be too limited. You can also upload R functions which need to be named 'scale_function' as in the following example.

# Input: The parameter given to the function is a dataframe 'dfItems' with the columns
# representing the item data of a single questionnaire e.g., item1; item2; item3, ...
# The column names should be the item names i.e., name in the xlsform.
# The data frame has a single row as it only represents data of one questionnaire.

# Thus, the input could look like this:

# item1 item2 item3 item4 item5
# 4 6 2 0 1

# Output:The function should return a data frame structured like the example below:

# scale value scaleMin scaleMax mean sd plotGroup
# 1 somatic_symptoms 5 0 12 NA NA 1
# 2 sleep 2 0 10 NA NA 1
# 3 suicidality 1 0 1 NA NA 1

# The data frame has a long format if there are multiple scales

scales_function = function(dfItmes){

anyNotFalse = function(x){any(x) | any(}

df = dfItems %>%
item4 = as.logical(item24),
item5 = as.logical(item25)

df = df %>%
somatic_symptoms = mean(item1, item2, na.rm = T),
sleep = item3,
suicidality = c(item4, item5) %>% anyNotFalse() %>% as.numeric()
) %>%
pivot_longer(cols = everything(),values_to = "value", names_to = "scale")

dfS = data.frame(df, scaleMin = 0, scaleMax = c(4,4,4,4,4,4,4,4,4,4,1,1), mean = NA, sd = NA, plotGroup = c(2,2,1,2,2,2,2,2,1,2,3,3))

# Run minimum plausibility check

if(!all(c("scale" ,"value") %in% colnames(dfS))){print("scale and value columns are required as output of scales_function")}

# Return results



Make sure that the shiny server has the required packages. Please assign the name 'scales_function' as name for the script when uploading it.

Creating the button

Please refer to this section of how to create the button for the patient reports.