OSAS Content Analysis¶

This notebook fosters the reproducibility of the following paper:

  • Gauld C, Baillieul S, Martin VP, Richaud A, Pelou M, Abi-Saab P,Coelho J, Philip P, Pépin JL, Micoulaud-Franchi JA. What evaluate obstructive sleep apnea patient-based screening questionnaires? A systematic and quantified item content analysis. Under review

If you want to compute the same metrics with you own data, we redirect you towards our generic content analysis GitHub https://github.com/vincentpmartin/generic_content_analysis

⚠️ PLEASE READ BEFORE DOING ANYTHING ⚠️¶

Welcome to this online coding environment ! You are currently running a Jupyter notebook that we hope to be usefull for content analysis of questionnaires.

Each cell can be ran individually (pressing the "Play" ▶ button or pressing CTRL+ENTER in the each cell). In order to make everything run smoothly, it is strongly recommended to run them in order.

RECOMMANDED: You can also run all the cells at the same time : "Run" → "Run All Cells".

At the end of the execution, you will have the opportunity to save all yours results in an HTML file, executing "File" → "Save and Export Notebook as" → "HTML"

If you have chosen to run every cell individually, please begin by running the following cell that imports all the required package for our code to work correctly ↓


1. Analysis of the number and frequency of symptoms¶

In a first step, we analyse the frequency of the symptoms.

Histogram of number of symptoms¶

Sorted by number of occurences¶

The figure has been save in the online folder (📁 symbol on the left) under the name figure1_histogram_1.pdf.
You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you need it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!

Sorted by category¶

The figure has been save in the online folder (📁 symbol on the left) under the name figure2_histogram_2.pdf.
You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you need it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!

Number of symptoms by questionnaire¶

Specific symptoms Compound symptoms Total
ASA 9 4 13
SA-SDQ 10 1 11
STOP-Bang 7 2 9
Berlin 8 1 9
Haraldsson 3 4 7
NoSAS 5 0 5
STOP 3 2 5
GOAL 4 0 4
OSA 50 4 0 4
AS 2 2 4
Wisconsin Q 3 0 3

The table has been save in the online folder (📁 symbol on the left) under the name table1_symptoms_per_questionnaire.xlsx.
You can change the name and the format of the file changing the name in the sympt_per_questionnaire.to_excel() function.
⚠️ If you need it, save the excel file on your local computer : these online file will be deleted as soon as you quit this page!

Symptoms that are in classifications but not in questionnaires¶

References list is empty

Number of symptoms in each category for each questionnaire¶

C:\Users\Vincent\AppData\Local\Temp\ipykernel_6396\3312803415.py:5: DeprecationWarning:

In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`

C:\Users\Vincent\AppData\Local\Temp\ipykernel_6396\3312803415.py:5: DeprecationWarning:

In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`

C:\Users\Vincent\AppData\Local\Temp\ipykernel_6396\3312803415.py:5: DeprecationWarning:

In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`

ASA SA-SDQ STOP-Bang Berlin Haraldsson NoSAS STOP GOAL OSA 50 AS Wisconsin Q
OSA symptoms 4 6 2 4 2 1 2 1 2 3 3
Sleep-related symptoms 4 1 2 3 5 0 2 0 0 0 0
Clinical characteristics 5 4 5 2 0 4 1 3 2 1 0

The table has been save in the online folder (📁 symbol on the left) under the name table2_categorie_per_questionnaire.xlsx.
You can change the name and the format of the file changing the name in the cat_per_questionnaire.T.to_excel() function.
⚠️ If you need it, save the excel file on your local computer : these online file will be deleted as soon as you quit this page!

Distribution across the categories of the symptoms measured by each questionnaire¶

(i.e. same thing as before, but normalized by questionnaire (sum across lines equals 1)).

Figure 3 has been save in the online folder (📁 symbol on the left) under the name figure3_heatmap.pdf. You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you need it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!


2. Analysis and data vizualisation of content analysis Figure¶

Content Analysis Figure¶

The figure has been save in the online folder (📁 symbol on the left) under the name figure4_radial.pdf. You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you need it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!

Overlap between questionnaires - Jaccard Index¶

In order to estimate the overlap between the symptoms measured by the questionnes, calculate the Jaccard index, which is defined as the number of symmtoms that are measured by both questionnaires, divided by the number of unique symptoms measured both questionnaires.

Jaccard index of symptom for each pair of questionnaire¶

First, we compute the Jaccard index for each pair of questionnaires and plot it using a heatmap.

ASA SA-SDQ STOP-Bang Berlin Haraldsson NoSAS STOP GOAL OSA 50 AS Wisconsin Q
ASA 1.000000 0.263158 0.375000 0.375000 0.333333 0.200000 0.285714 0.133333 0.062500 0.307692 0.230769
SA-SDQ 0.263158 1.000000 0.333333 0.250000 0.125000 0.142857 0.230769 0.250000 0.153846 0.153846 0.166667
STOP-Bang 0.375000 0.333333 1.000000 0.384615 0.230769 0.400000 0.555556 0.444444 0.181818 0.181818 0.200000
Berlin 0.375000 0.250000 0.384615 1.000000 0.230769 0.166667 0.400000 0.181818 0.181818 0.300000 0.333333
Haraldsson 0.333333 0.125000 0.230769 0.230769 1.000000 0.090909 0.333333 0.000000 0.100000 0.222222 0.250000
NoSAS 0.200000 0.142857 0.400000 0.166667 0.090909 1.000000 0.000000 0.500000 0.125000 0.125000 0.142857
STOP 0.285714 0.230769 0.555556 0.400000 0.333333 0.000000 1.000000 0.125000 0.125000 0.285714 0.333333
GOAL 0.133333 0.250000 0.444444 0.181818 0.000000 0.500000 0.125000 1.000000 0.142857 0.142857 0.166667
OSA 50 0.062500 0.153846 0.181818 0.181818 0.100000 0.125000 0.125000 0.142857 1.000000 0.142857 0.166667
AS 0.307692 0.153846 0.181818 0.300000 0.222222 0.125000 0.285714 0.142857 0.142857 1.000000 0.750000
Wisconsin Q 0.230769 0.166667 0.200000 0.333333 0.250000 0.142857 0.333333 0.166667 0.166667 0.750000 1.000000

Table 3 has been save in the online folder (📁 symbol on the left) under the name table3_jaccard_pairs.xlsx.
You can change the name and the format of the file changing the name in the jaccard_table.to_excel() function.
⚠️ If you need it, save the excel file on your local computer : these online file will be deleted as soon as you quit this page!

The figure has been save in the online folder (📁 symbol on the left) under the name figure5_heatmap_jaccard.pdf.
You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you want it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!

Avg. Jaccard index¶

Then, we compute the average of Jaccard index for each questionnaire with other questionnaires (excluding the references).

Avg. Jaccard Index
ASA 0.256650
SA-SDQ 0.206948
STOP-Bang 0.328735
Berlin 0.280402
Haraldsson 0.191634
NoSAS 0.189329
STOP 0.267442
GOAL 0.208698
OSA 50 0.138236
AS 0.261201
Wisconsin Q 0.274029
Average Jaccard index (wo references): 0.23666 (sd: 0.0542)

Table 4 has been save in the online folder (📁 symbol on the left) under the name table4_jaccard_average_questionnaires.xlsx.
You can change the name and the format of the file changing the name in the jaccard.to_excel() function.
⚠️ If you need it, save the excel file on your local computer : these online file will be deleted as soon as you quit this page!

Correlation between the number of symptoms and the average Jacquart index for each questionnaire¶

Avg. Jaccard Index Specific symptoms Compound symptoms Total
ASA 0.256650 9 4 13
SA-SDQ 0.206948 10 1 11
STOP-Bang 0.328735 7 2 9
Berlin 0.280402 8 1 9
Haraldsson 0.191634 3 4 7
NoSAS 0.189329 5 0 5
STOP 0.267442 3 2 5
GOAL 0.208698 4 0 4
OSA 50 0.138236 4 0 4
AS 0.261201 2 2 4
Wisconsin Q 0.274029 3 0 3
Correlation between Jaccard Index and number of specific symptoms:  SignificanceResult(statistic=0.0, pvalue=1.0)
Correlation between Jaccard Index and number of compound symptoms:  SignificanceResult(statistic=0.24545784641604232, pvalue=0.46691618386154077)
Correlation between Jaccard Index and total number of symptoms:  SignificanceResult(statistic=0.11521838449545894, pvalue=0.7358609458354772)

Jaccard index of symptoms for each pair of questionnaire for each category¶

Computing the same metric (average of average) for each category of questionnaires.

Avg. Jaccard Index
OSA symptoms 0.393983
Sleep-related symptoms 0.319524
Clinical characteristics 0.213062

Table 5 has been save in the online folder (📁 symbol on the left) under the name table5_jaccard_categories.xlsx.
You can change the name and the format of the file changing the name in the res.to_excel() function.
⚠️ If you need it, save the excel file on your local computer : these online file will be deleted as soon as you quit this page!

Computing the same metric (average of average) for each subcategory.

C:\Users\Vincent\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\numpy\core\fromnumeric.py:3464: RuntimeWarning:

Mean of empty slice.

C:\Users\Vincent\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\numpy\core\_methods.py:192: RuntimeWarning:

invalid value encountered in scalar divide

C:\Users\Vincent\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\numpy\core\fromnumeric.py:3464: RuntimeWarning:

Mean of empty slice.

C:\Users\Vincent\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\numpy\core\_methods.py:192: RuntimeWarning:

invalid value encountered in scalar divide

Avg. Jaccard Index
Snoring 0.555556
Breath abnormalities-related complaints 0.250000
Breath abnormalities observations 1.000000
Context NaN
Sleepiness 0.625000
Awakening 1.000000
Insomnia NaN
Sociodemographic 0.700000
Anthropometric 0.500000
Comorbidity 0.750000
Anatomical airway 0.333333

Sunburst Plot¶

The figure has been save in the online folder (📁 symbol on the left) under the name figure6_sunburst_plot.pdf.
You can change the name and the format of the file changing the name in the fig.write_image() function.
⚠️ If you want it, save the figure on your local computer : these online file will be deleted as soon as you quit this page!


Export to html¶

You have reached the end of this notebook. If you want to save the whole page, you can download it to html with dynamic figures:

  • "File" → "Save and Export Notebook as" → "HTML"