I'm trying to replicate the solution from this comment using reactive input values through the shiny app, but I can't seem to get dr4pl to recognize the input values as a column of data. I've tried assigning input as a variable, subsetting it with data[[]], etc.
I've created a CSV that contains the example data in the link.
! curve C1 C1 C1 C1 C1 C1 C1 C1 C1 C2 C2 C2 C2 C2 C2 C2 C2 C2 C3 C3 C3 C3 C3 C3 C3 C3 C3
! POC 1.07129314 0.9112628 0.97914297 0.95904437 0.8850967 0.84338263 0.75843762 0.61319681 0.52635571 0.84563087 1.24435113 1.11757648 0.82383523 0.82763447 0.72585483 0.31953609 0.15056989 0.10057988 0.57384256 0.65984339 0.81439758 0.84572057 0.62797088 0.30800934 0.08957274 0.06360764 0.04451161
! dose 0.078125 0.15625 0.3125 0.625 1.25 2.5 5 10 20 0.078125 0.15625 0.3125 0.625 1.25 2.5 5 10 20 0.078125 0.15625 0.3125 0.625 1.25 2.5 5 10 20
Edit: The previous error was due to me forgetting the get(), leading to the values called being empty.
Current error
Error in ==: comparison (==) is possible only for atomic and list types
ColID appears to lose the full context of input$z? The class of ColID is the same as the example, so not sure what I'm missing
library(shiny)
library(tidyverse)
library(plotly)
library(dr4pl)
library(data.table)
ui <- fluidPage(# Application title
sidebarLayout(
sidebarPanel(
fileInput('file', "Choose CSV File"),
uiOutput('X_dropdown'),
uiOutput('Y_dropdown'),
uiOutput('Z_dropdown'),
uiOutput('IC50_Checkbox'),
),
mainPanel(plotlyOutput("Plot"),
plotlyOutput("P_IC50_table"))
))
# Define server logic required to draw graph
server <- function(input, output, session) {
#saves uploaded file as a reactive output, file can be changed
dta <- reactive({
req(input$file)
read.csv(input$file$datapath, header = T)
})
output$X_dropdown <- renderUI({
req(dta())
selectInput('x', "X", names(dta()), selected = "dose")
})
output$Y_dropdown <- renderUI({
req(dta())
selectInput('y', "Y", names(dta()), selected = "POC")
})
output$Z_dropdown <- renderUI({
req(dta())
selectInput('z', "Color", names(dta()), selected = "curve")
})
output$IC50_Checkbox <- renderUI({
req(dta())
checkboxInput("ic50", "Calculate ICXX?", value = F)
})
output$Plot <- renderPlotly({
req(dta())
req(input$x)
if (input$ic50 == T) {
#Assign functions to variables
multiIC <- function(data,
colDose, colResp, colID,
inhib.percent,
...)
{
# Get curve IDs
locID <- unique(data[[colID]])
# Prepare a vector to store IC50s
locIC <- rep(NA, length(locID))
# Calculate IC50 separately for every curve
#seq_along takes the length of the sequence
for (ii in seq_along(locID)) {
# Subset a single dose response
locSub <- data[get(colID) == locID[[ii]], ]
# Calculate IC50
locIC[[ii]] <- dr4pl::IC(
dr4pl::dr4pl(dose = locSub[[colDose]],
response = locSub[[colResp]],
...),
inhib.percent)
}
return(data.frame(id = locID,
x = locIC))
}
#changed data
dfIC50 <- multiIC(data = dta(),
colDose = input$x,
colResp = input$y,
colID = input$z,
inhib.percent = 50
)
#browser()
IC50_table <- data.frame(id = locID, x = locIC)
ggplotly(
width = 500,
height = 500,
ggplot(data = dta(),
aes(
x = .data[[input$x]],
y = .data[[input$y]],
color = as.factor(.data[[input$z]])
)) +
labs(color = "") +
geom_vline(data = IC50_table, aes(xintercept = x))
)
output$P_IC50_table <- renderTable({
#Attempt to add in IC50 curve
IC50_table
})
} else{}
})
}
# Run the application
shinyApp(ui = ui, server = server)