-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy path01_rareinsight.R
More file actions
1341 lines (1253 loc) · 51.9 KB
/
01_rareinsight.R
File metadata and controls
1341 lines (1253 loc) · 51.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#Check if packages are downloaded
if (!require("shiny"))
install.packages("shiny")
if (!require("shinydashboard"))
install.packages("shinydashboard")
if (!require("shinyalert"))
install.packages("shinyalert")
if (!require("progress"))
install.packages("progress")
if (!require("data.table"))
install.packages("data.table")
if (!require("vcfR"))
install.packages("vcfR")
if (!require("DT"))
install.packages("DT")
if (!require("rmarkdown"))
install.packages("rmarkdown")
if (!require("shinyjs"))
install.packages("shinyjs")
if (!require("shinyWidgets"))
install.packages("shinyWidgets")
#Load packages
library(shiny)
library(shinydashboard)
library(shinyalert)
library(progress)
library(data.table)
library(vcfR)
library(DT) # For interactive tables
library(rmarkdown)
library(shinyjs)
library(shinyWidgets)
# Increase file size
options(shiny.maxRequestSize = 60 * 1024^2)
# Render Rmd to HTML once before the app runs
# Set up paths relative to the app file location
app_dir <- getwd()
rmds <- list(
glossary = "glossary.Rmd",
basic_genetics = "basic_genetics.Rmd",
rare_diseases = "rare_diseases.Rmd",
genetic_resources_guide = "genetic_resources_guide.Rmd"
)
# Create output dir
if (!dir.exists(file.path(app_dir, "www"))) dir.create(file.path(app_dir, "www"))
# Render Rmds to www/*.html
for (rmd in rmds) {
input_file <- file.path(app_dir, rmd)
output_file <- file.path(app_dir, "www", sub("\\.Rmd$", ".html", basename(rmd)))
rmarkdown::render(input_file, output_file = output_file, output_format = "html_document")
}
#Set UI function
ui <- fluidPage(
useSweetAlert(), # Important for confirmSweetAlert
#textOutput("user_type"),
dashboardPage(
dashboardHeader(title = span(
img(src = "rareinsight_final.png", height = 50), "RareInsight"
)),
dashboardSidebar(sidebarMenu(
menuItem("Home ", tabName = "home", icon = icon("home")),
menuItem(
"Understanding your genetics",
tabName = "understanding_genetics",
icon = icon("education", lib = "glyphicon")
),
menuItem(
"Services",
icon = icon("bar-chart"),
menuSubItem(
"Input User Information",
tabName = "input_user_info",
icon = icon("user-circle")
),
menuSubItem("VCF Panel", tabName = "vcfpanel", icon = icon("file")),
menuSubItem(
"Search Panel",
tabName = "Search",
icon = icon("search", lib = "glyphicon")
),
menuSubItem(
"Diagnostic Report",
tabName = "diagnostic_report",
icon = icon("line-chart"))
),
menuItem(
"Acknowledgement",
tabName = "acknow",
icon = icon("handshake"))
)
),
dashboardBody(
useShinyjs(),
useShinyalert(),
tags$head(tags$style(
HTML(
'
/* logo */
.skin-blue .main-header .logo {
background-color: #030637;
}
/* navbar (rest of the header) */
.skin-blue .main-header .navbar {
background-color: #030637;
}
/* logo when hovered */
.skin-blue .main-header .logo:hover {
background-color: #030637;
}
/* main sidebar */
.skin-blue .main-sidebar {
background-color: #3C0753;
}
/* active selected tab in the sidebarmenu */
.skin-blue .main-sidebar .sidebar .sidebar-menu .active a{
background-color: #9f16db;
}
/* other links in the sidebarmenu */
.skin-blue .main-sidebar .sidebar .sidebar-menu a{
background-color: ;
color: #FFFFFF
}
/* other links in the sidebarmenu when hovered */
.skin-blue .main-sidebar .sidebar .sidebar-menu a:hover{
background-color: #030637;
}
/* toggle button when hovered */
.skin-blue .main-header .navbar .sidebar-toggle:hover{
background-color: #3C0753;
}
/* body */
.content-wrapper, .right-side {
background-color: #FFFFFF ;
}
'))),
tabItems(
tabItem(
tabName = "home",
fluidRow(
h3("About RareInsight"),
p(
style = "text-align: justify;",
"Following a confirmed genetic diagnosis, rare disease patients and their families encounter significant challenges in accessing diagnostic information and support. Patients and non-specialists are increasingly expected to interpret and share test results; however, existing standards are primarily designed for specialists. These standards fail to address the needs of resource-limited populations where low genomic literacy hampers accurate dissemination of genetic results. This research introduces RareInsight, an open-source, interactive dashboard designed to enhance the accessibility, comprehension, and collaboration of genetic data among patients, caregivers, clinicians, and researchers. Developed using shinydashboard, RareInsight was evaluated using whole exome sequencing data from skeletal dysplasia patients. It allows users to input and view Variant Call Format (VCF) files and includes a searchable ClinVar variant table with filtering options, providing access to multiple resources based on search terms. RareInsight aims to simplify the dissemination of complex genetic information beyond the clinical setting. This dashboard serves as a pilot study demonstrating the potential of patient-centred interactive dashboards for the rare disease community."
),
h3("By promoting knowledge exchange, RareInsight aims to:"),
p(
"1- Simplify the complex process of understanding rare disease diagnoses as a patient or caregiver."
),
p(
"2- Present ClinVar variant data in a user-friendly, searchable format, accessible to both specialists and non-specialists."
),
p(
"3- Encourage patient empowerment by improving genomic literacy in the rare disease community, specifically in Africa."
),
p(
"4- Bridge the gap between clinical data and personal understanding through intuitive data visualization and educational resources."
),
p(
"5- Serve as a template for future rare disease tools, promoting open-source."
),
column(width = 12, div(
style = "text-align: center;",
tags$img(
src = "pic.jpg",
width = "20%",
height = 150
) # Adjust width and height as needed
)),
fluidRow(column(
width = 12,
tags$video(
src = "https://github.com/omicscodeathon/rareinsight/blob/main/www/RareInsight_tutorial.mp4",
type = "video/mp4",
width = "100%",
controls = TRUE
))
)
)
),
tabItem(tabName = "understanding_genetics",
tabsetPanel(
tabPanel("Glossary",
downloadButton("download_glossary", "Download Glossary (HTML)"),
uiOutput("view_glossary")
),
tabPanel("Basic Genetics",
downloadButton("download_basic_genetics", "Download Basic Genetics (HTML)"),
uiOutput("view_basic_genetics")
),
tabPanel("Rare Diseases",
downloadButton("download_rare_diseases", "Download Rare Diseases (HTML)"),
uiOutput("view_rare_diseases")
)
)
),
tabItem(tabName = "service", h1("User Data Inputs")),
tabItem(
tabName = "input_user_info",
h1(" User Data Inputs"),
fluidRow(
column(6, textInput(inputId = "name", label = "Name")),
column(6, textInput(inputId = "surname", label = "Surname")),
column(6, textInput(inputId = "ethnicity", label = "Ethnicity")),
column(6, dateInput(inputId = "dob", label = "Date of Birth")),
#TODO: User must be able to select year from search
column(
12,
textInput(inputId = "clinical_diagnosis", label = "Clinical Diagnosis")
),
column(12, textInput(inputId = "phenotype", label = "Phenotype")),
column(
12,
selectInput(
inputId = "test_performed",
label = "Test Performed",
choices = c("WES", "WGS", "Gene Panel")
)
),
downloadButton(outputId = "download_button", label = "Download User Info")
)
),
tabItem(tabName = "Search", h1("Search Panel"), fluidRow(
wellPanel(
selectInput(
"search_type",
"Search Type:",
choices = c("Gene", "Variant", "Disorder", "dbSNP", "ClinVar"),
selected = "Gene"
),
textInput("search_input", "Enter Search Term:", ""),
actionButton("search_button", "Search"),
DTOutput("search_results"),
# Warning
tags$h4(
"REMINDER: This tool is for educational purposes only and does not replace professional medical or genetic consultation. Users are strongly encouraged to consult a genetic counsellor or clinician before drawing conclusions from variant information."
),
# Heading with examples
tags$h4(style = "opacity: 0.5;", "Examples:"),
tags$p(style = "opacity: 0.5;", "For ClinVar enter the accession e.g. RCV000007523."),
tags$p(
style = "opacity: 0.5;",
"For dbSNP enter the accession number only (remove rs) e.g. 137854557."
),
tags$p(style = "opacity: 0.5;", "For Gene enter a GeneSymbol e.g. BRCA1."),
tags$p(
style = "opacity: 0.5;",
"For Disorder enter the name of the disorder e.g. Noonan Syndrome."
),
tags$p(
style = "opacity: 0.5;",
"For Variant enter the amino acid change (c.44C>T), protein change (p.Pro15Leu) or the reference sequence from the GenBank database (NM_004006.3)."
)
)
)),
tabItem(
tabName = "vcfpanel",
h1("VCF Panel"),
fileInput("input_file", "Upload VCF File", accept = c(".vcf.gz")),
tabsetPanel(tabPanel("Results", fluidRow(
wellPanel(
title = "Variant Information",
solidHeader = TRUE,
status = "primary",
div(style = "overflow-x: scroll; width: 100%;", dataTableOutput("variant_table"))
)
)), tabPanel("Graphs", fluidRow(
tabsetPanel(box("plot1", plotOutput("PLOT1")), box("plot2", plotOutput("PLOT2")))
)))
),
tabItem(tabName = "diagnostic_report", tabsetPanel(
tabPanel(
"Disorder Information",
h2("Disorder Information"),
p(
"Here is some information on the selected disorder, accession or gene from the Clinvar search panel."
),
p(
"REMINDER: This tool is for educational purposes only and does not replace professional medical or genetic consultation. Users are strongly encouraged to consult a genetic counsellor or clinician before drawing conclusions from variant information."
),
fluidRow(
column(
width = 12,
actionButton(
"buttonOMIM",
label = "OMIM",
icon = icon("up-right-from-square")
),
p(
style = "text-align: justify;",
"Online Mendelian Inheritance in Man (OMIM) is a comprehensive database of human genes and genetic phenotypes. It catalogues information about genetic disorders and their associated genes, including clinical descriptions, molecular mechanisms, and inheritance patterns. Clinicians and researchers can use OMIM to explore the genetic basis of rare diseases and access curated information about specific disorders."
),
p(
style = "text-align: justify;",
"This button works if you entered: Gene, ClinVar, dbSNP or Disorder"
)
),
column(
width = 12,
actionButton(
"buttonPubMed",
label = "PubMed",
icon = icon("up-right-from-square")
),
p(
style = "text-align: justify;",
"PubMed provides clinicians with a repository of literature, aiding in evidence-based practices into patient care, particularly in rare diseases where information is limited. For researchers, PubMed is useful for conducting literature reviews, identifying research gaps, and fostering collaboration to advance understanding and treatment of rare diseases."
),
p(style = "text-align: justify;", "This button works if you entered: Gene")
),
column(
width = 12,
actionButton(
"buttonNORD",
label = "NORD",
icon = icon("up-right-from-square")
),
p(
style = "text-align: justify;",
"NORD's rare disease database is a comprehensive resource providing information on various rare disorders, including their symptoms, causes, treatments, and available support services. It serves as a valuable tool for clinicians and researchers seeking reliable information and resources."
),
p(style = "text-align: justify;", "This button works if you entered: Disorder")
)
)
),
tabPanel(
"Clinician and Researcher Support",
h2("Information for clinician and researchers"),
p("This is the content for Clinician and Researcher Support."),
fluidRow(
column(
width = 6,
actionButton("buttonClinVar", label = "ClinVar", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"ClinVar is a public archive of reports and interpretations of the clinical significance of genomic variants. It aggregates data from various sources. It can be used to evaluate the significance of genetic variants in the context of rare diseases, aiding in diagnosis, treatment decisions, and research investigations."),
p(style = "text-align: justify;", "This button works if you entered: Gene or a ClinVar accession")
),
column(
width = 6,
actionButton("buttongenomAD", label = "genomAD", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"The Genome Aggregation Database is a resource that aggregates sequencing data from a diverse range of populations. It provides information about genetic variation, including allele frequencies, functional annotations, and population-specific patterns. The frequency and distribution of genetic variants across populations can be assessed aiding in interpretation of rare and common variants in many populations."),
p(style = "text-align: justify;", "This button works if you entered: Gene")
),
column(
width = 6,
actionButton("buttonPubMed1", label = "PubMed", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"PubMed provides clinicians and researchers with an updated repository of literature on disorders and genes aiding in an improved understanding of rare diseases."),
p(style = "text-align: justify;", "This button works if you entered: Gene or Disorder")
),
column(
width = 6,
actionButton("buttonGeneReviews", label = "GeneReviews", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"GeneReviews is a comprehensive resource providing expert-authored, peer-reviewed information about genetic conditions. It offers detailed summaries of specific genes and the associated diseases. It can be used to inform patient care and research efforts."),
p(style = "text-align: justify;", "This button works if you entered: Gene")
),
column(
width = 6,
actionButton("buttonVarsome", label = "Varsome", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"Varsome is a variant interpretation tool that helps clinicians and researchers analyze and interpret genetic variants. It integrates data from various sources to provide variant annotations and interpretations which can be used to assess the clinical significance of variants in rare diseases."),
p(style = "text-align: justify;", "This button works if you entered: Gene, dbSNP, or Disorder")
),
column(
width = 6,
actionButton("buttonLitVar", label = "LitVar", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"LitVar is a database that aggregates information about variants, genes and disorders mentioned in literature. It provides annotations and links to relevant publications, helping researchers and clinicians stay updated on the latest findings related to rare diseases."),
p(style = "text-align: justify;", "This button works if you entered: Gene, dbSNP, or Disorder")
),
column(
width = 6,
actionButton("buttondbSNP", label = "dbSNP", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"The Single Nucleotide Polymorphism Database (dbSNP) is a repository that catalogs genetic variation. It can be used to explore genetic variation across populations and understand how specific variants may be associated with rare diseases."),
p(style = "text-align: justify;", "This button works if you entered: Gene or dbSNP")
),
column(
width = 6,
actionButton("buttonNORD1", label = "NORD", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"NORD provides a comprehensive resource for information on rare disorders, including their symptoms, causes, treatments, etc. It serves as a valuable tool for seeking reliable information and resources."),
p(style = "text-align: justify;", "This button works if you entered: Disorder")
)
)
),
tabPanel(
"Patient Support",
h2("Patient Support"),
p("Support page for rare disease patients and families"),
fluidRow(
column(
width = 6,
actionButton("buttonRareConnect", label = "RareConnect", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"RareConnect is an online platform that connects people affected by rare diseases worldwide. It hosts various disease-specific communities where patients, caregivers, and advocates can share experiences, ask questions, and provide support to each other.")
),
column(
width = 6,
actionButton("buttonRAReSOURCE", label = "RAReSOURCE", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"RARe-SOURCE provides a list of rare diseases with their gene associations, links to related features within the database and links to external data sources.")
),
column(
width = 6,
actionButton("buttonRDSA", label = "RDSA", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"Rare Diseases South Africa is a non-profit organisation which advocates for rare disease patients to achieve greater recognition, support, improved health service and better overall quality of life. It allows patients and families to access local support groups, advocacy organizations, and healthcare resources.")
),
column(
width = 6,
actionButton("buttonGARD", label = "GARD", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"The Genetic and Rare Diseases Information Center (GARD) provides access to comprehensive information about rare diseases. It allows users to search for specific diseases and access resources such as overviews, symptoms, causes, treatment options, and research updates."),
p(style = "text-align: justify;", "This button works if you entered: Disorder")
),
column(
width = 6,
actionButton("buttonNORDORG", label = "NORD Patient Organizations", icon = icon("up-right-from-square")),
p(style = "text-align: justify;",
"NORD's patient organizations database raises awareness about rare disorders by connecting affected individuals and families with relevant support groups and advocacy organizations around the world.")
)
)
),
tabPanel("Genetic Resources Guide",
h3("RareInsight: Simplifying Online Genetic Resources"),
downloadButton("download_genetic_resources", "Download as HTML"),
br(), br(),
uiOutput("view_genetic_resources")
),
tabItem(
tabName = "acknow",
h2("Contributors:"),
h4(
HTML(
"<a href='https://github.com/Kimmiecc19'>KC Coetzer</a>: Division of Molecular Biology and Human Genetics, Department of Biomedical Sciences, Faculty of Medicine and Health Sciences, Stellenbosch University, Cape Town, South Africa"
)
),
h4(
HTML(
"<a href='https://github.com/Zemzemfiras1'>F Zemzem</a>: Laboratory of Cytogenetics, Molecular Genetics and Biology of Reproduction CHU Farhat Hached Sousse, Higher Institute of Biotechnology of Monastir, University of Monastir, Tunisia"
)
),
h4(
HTML(
"<a href='https://github.com/AkurutEva'>E Akurut</a>: African Centre of Excellence in Bioinformatics and Data-intensive Sciences, Infectious Disease Institute, Makerere University, Kampala, Uganda"
)
),
h4(
HTML(
"<a href='https://github.com/gwiafe'>G Wiafe</a>: Department of Biomedical Sciences, University of Cape Coast, Cape Coast, Ghana"
)
),
h4(
HTML(
"<a href='https://github.com/laitanawe'>OI Awe</a>: African Society for Bioinformatics and Computational Biology, Cape Town, South Africa"
)
),
h2("Thank you to the following organizations for their support:"),
h4(
"African Society for Bioinformatics and Computational Biology",
img(
src = "asbcb-logo.png",
height = 50,
width = 50
)
),
h2("For more information: "),
h4(
HTML(
"<a href='https://github.com/omicscodeathon/rareinsight/'>GitHub</a>: Read more about this research and access all our scripts."))
) # close ackowledgements tab
) # Clost tabitem (diagnostic report)
) # close diagnostic_report panel
) # close tabItems
) # close dashboardBody
)) # Close fuidPage and dashboardPage
# Define server logic
server <- function(input, output, session) {
# Download files as HTML
output$download_glossary <- downloadHandler(
filename = function() {
paste0("Glossary_", Sys.Date(), ".html")
},
content = function(file) {
file.copy("www/glossary.html", file)
},
contentType = "text/html"
)
output$download_basic_genetics <- downloadHandler(
filename = function() {
paste0("Basic_Genetics_", Sys.Date(), ".html")
},
content = function(file) {
file.copy("www/basic_genetics.html", file)
},
contentType = "text/html"
)
output$download_rare_diseases <- downloadHandler(
filename = function() {
paste0("Rare_Diseases_", Sys.Date(), ".html")
},
content = function(file) {
file.copy("www/rare_diseases.html", file)
},
contentType = "text/html"
)
output$download_genetic_resources <- downloadHandler(
filename = function() {
paste0("Genetic_Resources_Guide_", Sys.Date(), ".html")
},
content = function(file) {
file.copy("www/genetic_resources_guide.html", file)
},
contentType = "text/html")
# Display HTML in dashboard
output$view_glossary <- renderUI({
tags$iframe(src = "glossary.html", style = "width:100%;height:800px;border:none;")
})
output$view_basic_genetics <- renderUI({
tags$iframe(src = "basic_genetics.html", style = "width:100%;height:800px;border:none;")
})
output$view_rare_diseases <- renderUI({
tags$iframe(src = "rare_diseases.html", style = "width:100%;height:800px;border:none;")
})
output$view_genetic_resources <- renderUI({
tags$iframe(src = "genetic_resources_guide.html", style = "width:100%;height:800px;border:none;")
})
# Trigger role selection on startup
observeEvent(TRUE, {
confirmSweetAlert(
inputId = "role_select",
title = "Welcome to RareInsight",
text = "Are you a patient/caregiver or clinician/researcher?",
btn_labels = c("Clinician/Researcher", "Patient/Caregiver"),
swalType = "question",
danger_mode = FALSE,
closeOnClickOutside = FALSE,
showCloseButton = FALSE,
timer = NULL
)
}, once = TRUE)
# Handle Patient/Caregiver selection
observeEvent(input$role_select, {
if (input$role_select) { # TRUE = Patient/Caregiver, FALSE = Clinician
showModal(modalDialog(
title = "Tell us a bit more",
radioButtons("q1", "Have you seen a geneticist?", choices = c("Yes", "No")),
radioButtons("q2", "Have you undergone any testing?", choices = c("Yes", "No")),
radioButtons("q3", "Do you have a confirmed diagnosis?", choices = c("Yes", "No")),
checkboxInput("disclaimer_ack",
"I understand this tool is for educational purposes only and does not replace professional consultation.",
value = FALSE),
footer = tagList(
actionButton("confirm_patient", "Continue", class = "btn-primary")
),
easyClose = FALSE
))
}
})
# Validate patient input
observeEvent(input$confirm_patient, {
if (!input$disclaimer_ack) {
showNotification("Please acknowledge the disclaimer to continue.", type = "error")
} else {
removeModal()
output$user_type <- renderText("You selected: Patient/Caregiver")
}
})
# For clinician selection
observeEvent(input$role_select, {
if (!input$role_select) {
output$user_type <- renderText("You selected: Clinician/Researcher")
}
})
# Define variant_summary
variant_summary <- reactiveVal(NULL)
observe({
withProgress(
message = 'Downloading and processing data...',
detail = 'This may take a while...',
value = 0,
{
# File paths
gz_file <- "www/variant_summary.txt.gz"
txt_file <- "www/variant_summary.txt"
# Function to download file if it doesn't exist
download_file <- function(url, dest_file) {
if (!file.exists(dest_file)) {
tryCatch({
download.file(url, destfile = dest_file, mode = "wb")
cat("...download complete...\n")
}, error = function(e) {
cat("Error downloading file:", e$message, "\n")
})
} else {
cat("...File already exists...\n")
}
}
# Download only if txt file doesn't exist
if (!file.exists(txt_file)) {
cat("...Checking for gz file to download...\n")
download_file(
"https://ftp.ncbi.nlm.nih.gov/pub/clinvar/tab_delimited/variant_summary.txt.gz",
gz_file
)
} else {
cat("...Text file already exists. Skipping download and unzip...\n")
}
# Unzip only if txt file doesn't exist but gz does
if (!file.exists(txt_file) && file.exists(gz_file)) {
cat("...Unzipping the file...\n")
tryCatch({
con <- gzfile(gz_file, "rt")
writeLines(readLines(con), txt_file)
close(con)
cat("...Unzipped successfully...\n")
}, error = function(e) {
cat("Error unzipping file:", e$message, "\n")
})
}
# Load data
if (file.exists(txt_file)) {
cat("...Reading the file into memory...\n")
variant_summary_data <- read.delim(txt_file, stringsAsFactors = FALSE)
variant_summary(variant_summary_data)
} else {
cat("ERROR: variant_summary.txt not found.\n")
}
}
)
})
# Downloadable user info content
output$download_button <- downloadHandler(
filename = function() {
paste(input$name, input$surname, Sys.Date(), ".pdf", sep = "")
},
content = function(file) {
# Create the R Markdown content
rmd_content <- sprintf(
'RAREINSIGHT REPORT
User Information :
__________________
Name: %s
Surname: %s
Ethnicity: %s
Date of Birth: %s
Clinical Diagnosis (OMIM): %s
Phenotype (HPO Terms): %s
Test Performed: %s',
input$name,
input$surname,
input$ethnicity,
input$dob,
input$clinical_diagnosis,
input$phenotype,
input$test_performed
)
img(src = "rareinsight_final.png", height = 50)
# Create a temporary file to store the R Markdown content
temp_rmd_file <- tempfile(fileext = ".Rmd")
# Write the R Markdown content to the temporary file
writeLines(rmd_content, temp_rmd_file)
# Render the R Markdown file to PDF
rmarkdown::render(temp_rmd_file, output_file = file)
# Remove the temporary R Markdown file
unlink(temp_rmd_file)
},
contentType = "application/pdf" # Set content type to PDF
)
# Observing search button click
observeEvent(input$search_button, {
search_term <- input$search_input
search_type <- input$search_type
req(search_term, search_type) # Ensure search term and type are available
if (nchar(search_term) > 0) {
# Define the column to search based on search type
search_column <- switch(
search_type,
"Gene" = "GeneSymbol",
"Variant" = "Name",
"Disorder" = "PhenotypeList",
"dbSNP" = "RS...dbSNP.",
"ClinVar" = "RCVaccession"
)
# Filter data based on search term and column
indices <- grep(search_term, variant_summary()[[search_column]], ignore.case = TRUE)
if (length(indices) > 0) {
filtered_data <- variant_summary()[indices, ]
output$search_results <- renderDT({
datatable(filtered_data, options = list(scrollX = TRUE))
})
} else {
output$search_results <- renderDT({
HTML("<p>No matching results found.</p>")
})
}
} else {
# If there's no search term, show an alert message
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
return()
}
})
observeEvent(input$buttonOMIM, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type)
if (nchar(search_term) > 0) {
omim_search_url <- ""
if (search_type %in% c("Gene", "ClinVar", "Disorder")) {
# Construct the OMIM search URL based on the search type
omim_search_url <- paste0(
"https://www.omim.org/search?index=entry&start=1&search=",
URLencode(search_term),
"&sort=score+desc%2C+prefix_sort+desc&limit=10&date_created_from=&date_created_to=&date_updated_from=&date_updated_to="
)
} else if (search_type == "dbSNP") {
# Check if "rs" is in the search term, if not, add it
if (!grepl("rs", search_term, ignore.case = TRUE)) {
search_term <- paste0("rs", search_term)
}
# Construct the OMIM search URL for dbSNP
omim_search_url <- paste0(
"https://www.omim.org/search?index=entry&start=1&search=",
URLencode(search_term),
"&sort=score+desc%2C+prefix_sort+desc&limit=10&date_created_from=&date_created_to=&date_updated_from=&date_updated_to="
)
}
browseURL(omim_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
})
### buttonClinVar
observeEvent(input$buttonClinVar, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type)
if (search_type %in% c("Gene", "ClinVar")) {
if (nchar(search_term) > 0) {
if (search_type == "Gene") {
# Construct the Clinvar search URL for gene
ClinVar_search_url <- paste0(
"https://www.ncbi.nlm.nih.gov/clinvar/?term=",
URLencode(search_term),
"%5Bgene%5D&redir=gene"
)
} else if (search_type == "ClinVar") {
# Construct the Clinvar search URL for RCVaccession
ClinVar_search_url <- paste0(
"https://www.ncbi.nlm.nih.gov/clinvar/?term=",
URLencode(search_term),
"&redir=rcv"
)
}
browseURL(ClinVar_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttonPubMed
observeEvent(input$buttonPubMed, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type) # Get the search term from the Search Panel
if (search_type %in% c("Gene")) {
if (nchar(search_term) > 0) {
if (search_type == "Gene") {
# Construct the PubMed search URL for gene only
PubMed_search_url <- paste0("https://pubmed.ncbi.nlm.nih.gov/?term=",
URLencode(search_term))
}
browseURL(PubMed_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttonPubMed1 in Clinician and research support panel
observeEvent(input$buttonPubMed1, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type) # Get the search term from the Search Panel
if (search_type %in% c("Gene", "Disorder")) {
if (nchar(search_term) > 0) {
# Construct the PubMed search URL for gene only
PubMed_search_url <- paste0("https://pubmed.ncbi.nlm.nih.gov/?term=",
URLencode(search_term))
browseURL(PubMed_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttonGeneReviews
observeEvent(input$buttonGeneReviews, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type) # Get the search term from the Search Panel
if (search_type %in% c("Gene")) {
if (nchar(search_term) > 0) {
if (search_type == "Gene") {
# Construct the GeneReviews search URL for gene only
GeneReviews_search_url <- paste0(
"https://www.ncbi.nlm.nih.gov/books/NBK1116/?term=",
URLencode(search_term),
"gene%20review"
)
}
browseURL(GeneReviews_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttonLitVar
observeEvent(input$buttonLitVar, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type) # Get the search term from the Search Panel
if (search_type %in% c("Gene", "Disorder")) {
if (nchar(search_term) > 0) {
# Construct the LitVar search URL for gene or disorder
if (length(strsplit(search_term, " ")[[1]]) > 1) {
search_term <- gsub(" ", "%20", search_term)
}
LitVar_search_url <- paste0(
"https://www.ncbi.nlm.nih.gov/research/litvar2/docsum?text=",
URLencode(search_term)
)
browseURL(LitVar_search_url) # Moved browseURL here
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
} else if (search_type == "dbSNP") {
if (nchar(search_term) > 0) {
# Check if "rs" is in the search term, if not, add it
if (!grepl("rs", search_term, ignore.case = TRUE)) {
search_term <- paste0("rs", search_term)
}
# Construct the LitVar search URL for dbSNP
LitVar_search_url <- paste0(
"https://www.ncbi.nlm.nih.gov/research/litvar2/docsum?variant=litvar@",
URLencode(search_term),
"%23%23&query="
)
browseURL(LitVar_search_url) # Moved browseURL here
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttonVarsome
observeEvent(input$buttonVarsome, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type)
if (search_type %in% c("Gene", "dbSNP", "Disorder")) {
if (nchar(search_term) > 0) {
if (search_type == "Gene") {
# Construct the Varsome search URL for gene
Varsome_search_url <- paste0("https://varsome.com/gene/hg38/",
URLencode(search_term))
} else if (search_type == "dbSNP") {
# Construct the Varsome search URL for dbSNP
Varsome_search_url <- paste0("https://varsome.com/variant/hg38/",
URLencode(search_term))
} else if (search_type == "Disorder") {
# Check if search term has more than one word, replace spaces with %20
if (length(strsplit(search_term, " ")[[1]]) > 1) {
search_term <- gsub(" ", "%20", search_term)
}
# Construct the Disorder search URL for disease name
Varsome_search_url <- paste0("https://varsome.com/search-results/",
URLencode(search_term))
}
browseURL(Varsome_search_url)
} else {
showModal(
modalDialog(
title = "Error",
"Please enter a search term in the Search Panel first.",
easyClose = TRUE
)
)
}
}
})
### buttondbSNP
observeEvent(input$buttondbSNP, {
search_term <- isolate(input$search_input)
search_type <- isolate(input$search_type)
if (search_type %in% c("Gene", "dbSNP")) {