Search code examples
rggplot2shinysurvival

Issue with R Shiny App --> Interactive Survival Plots


I am new to R Shiny and I am trying to build a Shiny Web App that produces a survival plot with two reactive inputs. The first input is the study (total=4). The second input is the groups (total=19) to compare survival curves. Ideally, these two inputs would allow me to see in a particular study, how group X survival curve compares to the survival curve of all other groups.

Here is a sample of my data:

ObsNum    UniqueID  Time Censored Group Group2 Study
1         523B95015   27        1    1     523     1
2         523B95014   27        1    1     523     1
3         523B85051   27        1    1     523     1
4         523B95009   27        1    1     523     1
5         523B85048   27        1    1     523     1
6         523B85050   27        1    1     523     1
7         675B89002   27        1    8     675     1
8         556B95006   27        1   12     556     1
9         556B85030   27        1   12     556     1
10        556B85044   27        1   12     556     1
11        556B95035   27        1   12     556     1
12        556B95000   27        1   12     556     1
13        556B95004   27        1   12     556     1
14        556B95002   27        1   12     556     1
15        756Y81172   27        1   17     756     1
16        741B95022   27        1   99     741     1
17        741B95020   27        1   99     741     1
18        619B92008   28        1    7     619     1
19        552B89003   28        1   10     552     1
20        101B94097   28        1   99     101     1
21        101B94098   28        1   99     101     1
22        618C84582   29        1   23     618     1
23        618C84580   29        1   23     618     1
24        618C84581   29        1   23     618     1
25        730B90003   29        1   99     730     1
26        646B42015   34        1    4     646     1
27        671B60009   35        1   17     671     1
28        612C80247   35        1   21     612     1
29        700C64500   35        1   99     791     1
30        101B89052   40        1   99     101     1
31        101B85047   40        1   99     101     1
32        101B95068   40        1   99     101     1
33        538B70011   51        1   10     538     1
34        689C85036   57        1    1     689     1
35        689C95450   57        1    1     689     1
36        556B85050   62        1   12     556     1
37        636B80005   62        1   23     636     1
38        636B92002   62        1   23     636     1
39        630B30005   70        1    2     630     1
40        642B80021   78        1    4     642     1
41        101B79173   86        1   99     101     1
42        523B81007  106        0    1     523     1
43        620B88003  106        0    2     620     1
44        642B40002  106        1    4     642     1
45        642B40001  106        1    4     642     1
46        581B81002  106        0    5     581     1
47        581B81001  106        0    5     581     1
48        573B95000  106        0    8     573     1
49        589B80015  106        0   15     589     1
50        589B80016  106        0   15     589     1
51        657B50013  106        0   15     657     1
52        657B43004  106        0   15     657     1
53        459B85085  106        0   21     459     1
54        459Y81171  106        0   21     459     1
55        101B75006  106        0   99     101     1
56        101SC8023  106        0   99     101     1
57        101B85122  106        0   99     101     1
58        101B55116  106        0   99     101     1
59        101B79086  106        0   99     101     1
60        101B95066  106        0   99     101     1
61        730B97005  106        0   99     730     1
62        741B85045  106        0   99     741     1
63        777B96001  106        0   99     777     1
64        556B85077    1        1   12     556     2
65        636B92003    1        1   23     636     2
66        101B94137    1        1   99     101     2
67        700C64500    5        1   99     791     2
68        463Y91171    6        1   20     463     2
69        618C84319    6        1   23     618     2
70        776C93046    6        1   99     776     2
71        556B95042    7        1   12     556     2
72        556B95043    7        1   12     556     2
73        556B97000    7        1   12     556     2
74        549B80069    7        1   17     549     2
75        573B95000   22        1    8     573     2
76        580B90024   22        1   16     580     2
77        523B81007   28        1    1     523     2
78        520B60012   32        1   16     520     2
79        520B70011   32        1   16     520     2
80        586B70008   33        1   16     586     2
81        586B80006   33        1   16     586     2
82        586B80011   33        1   16     586     2
83        586B80015   33        1   16     586     2
84        657B43004   34        1   15     657     2
85        636B99009   35        1   23     636     2
86        691B68018   36        1   22     691     2
87        657B50013   41        1   15     657     2
88        741B95031   42        1   99     741     2
89        620B88003   46        0    2     620     2
90        620B90008   46        0    2     620     2
91        581B81001   46        0    5     581     2
92        581B81002   46        0    5     581     2
93        552B99002   46        0   10     552     2
94        459B85085   46        0   21     459     2
95        459B95055   46        0   21     459     2
96        101B75006   46        0   99     101     2
97        101B55060   46        0   99     101     2
98        101B79086   46        0   99     101     2
99        101B79058   46        0   99     101     2
100       101B85122   46        0   99     101     2
101       101B89115   46        0   99     101     2
102       101B85047   46        0   99     101     2
103       101B94123   46        0   99     101     2
104       101B95091   46        0   99     101     2
105       101B95038   46        0   99     101     2
106       101D98001   46        0   99     101     2
107       730B97005   46        0   99     730     2
108       741B85045   46        0   99     741     2

Here is my code for the Shiny App:

library(shiny)
library(ggplot2)
library(survival)
library(survminer)
library(dplyr)
attach(tdata)
studychoices=unique(tdata$Study)
groupchoices=unique(tdata$Group)

# Define UI 
ui <- fluidPage(


titlePanel("Survival Data"),
    selectInput(inputId = "studyselector",label="Select a Study:", choices=studychoices),
    selectInput(inputId = "groupselector",label="Select a Group:", choices=groupchoices),
    plotOutput("p1")

)

# Define server logic
server <- function(input, output) {

filter=reactive({
    filteredData=tdata[tdata$Study==input$studyselector,]
    return(filteredData)
})

output$p1=renderPlot({
    fit=survfit(Surv(Time,Censored)~input$groupselector,data=filter())
    ggsurvplot(fit,data=filter(),pval=TRUE,xlim=c(0,max(Time)+1),
               title=paste("Study","INSERT HERE STUDY #", "Survival Plot for Group","INSERT HERE   GROUP #"),
               xlab="Time (Days)",
               ggtheme=theme(plot.title=element_text(hjust=0.5)))
    })

}

# Run the application 
shinyApp(ui = ui, server = server)

I have the following two questions:

1.) When I run the App, I get an error in an external window that reads, "Error: variable lengths differ (found for'input$groupselector'). There are no NAs in this data and I specified the data to be used is the filter() dataset based on the Study selection so I'm not sure why this error is popping up.

2.) How would I be able to dynamically change the Study # and the Group # in the title? I understand how to do that with a normal R function, but I'm a little lost with the Shiny set up.

Any help would be appreciated! Thank you!


Solution

  • Edited solution

    This should now work - have edited the Group column to be a binary in/out when passed to your reactive dataframe, which should colour the lines appropriately:

    library(tidyverse)
    library(survival)
    library(survminer)
    library(shiny)
    
    ui <- fluidPage(
    
    
      titlePanel("Survival Data"),
      selectInput(inputId = "studyselector",label="Select a Study:", choices=studychoices),
      selectInput(inputId = "groupselector",label="Select a Group:", choices=groupchoices),
      plotOutput("p1")
    
    )
    
    # Define server logic
    server <- function(input, output) {
    
      filter=reactive({
        filteredData=data[data$Study==input$studyselector,]
        filteredData['Group'] = ifelse(filteredData$Group==input$groupselector,
                                       input$groupselector,
                                       "Others")
        return(filteredData)
      })
    
      output$p1=renderPlot({
        fit=survfit(Surv(Time,Censored)~Group,data=filter())  # `Group` as variable to stratify by?
        ggsurvplot(fit,data=filter(),pval=TRUE,xlim=c(0,max(filter()$Time)+1),
                   title=paste("Study",
                               input$studyselector,  # paste these bits straight in
                               "Survival Plot for Group",
                               input$groupselector), # here too
                   xlab="Time (Days)",
                   ggtheme=theme(plot.title=element_text(hjust=0.5)))
      })
    
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    Do let me know in comments if there are any mistakes or further ideas/questions!

    comparing curves