Accessing data from a different data frame

Hello,

I'm trying to create an app that creates 2 different plots based on one user uploaded file. My approach is to create 2 different reactive data frames, that take the original uploaded raw data, but transform it differently based on the parameters needed for the plot. In addition, I'm using dplyr to filter/select columns for each reactive data frame.

However, every time I try to call the original uploaded data in the reactive functions, I get the following errors:
"no applicable method for 'select_' applied to an object of class "function"
"Result must have length 6, not 0"

For context, my uploaded data has 6 rows.

Code:
#This app allows users to upload 2x2/contingency table data in a pre-specified format, and in return, plots the data in several different forms.

#Load libraries
library(shiny)
library(ggplot2)
library(dplyr)
library(readxl)
library(tidyverse)
library(rlang)
library(DT)
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Define UI for overall application

#data upload
ui <- fluidPage(

Application title

titlePanel("Data Visualization -- 2x2 Analysis"),

tabsetPanel(
#----------------------------------------------------------------------------------------------------------------------------------------------------------
#Data upload tab
tabPanel("Upload File",
titlePanel("Upload CSV File"),

         #sidebar layout with input and output definitions--
         sidebarLayout(
           
           #sidebar panel for inputs --- 
           sidebarPanel(
             
             #input-- select file
             fileInput('file1', 'Choose CSV File', multiple = FALSE,
                       accept=c('text/csv', 
                                'text/comma-separated-values,text/plain', 
                                '.csv')),
             
             # Horizontal line ----
             tags$hr(),
             
             checkboxInput('header', 'Header', TRUE),
             radioButtons('sep', 'Separator',
                          c(Comma=',',
                            Semicolon=';',
                            Tab='\t'),
                          ','),
             radioButtons('quote', 'Quote',
                          c(None='',
                            'Double Quote'='"',
                            'Single Quote'="'"),
                          '"'),
             tags$hr(),
             
             # Input: Select number of rows to display ----
             radioButtons("disp", "Display",
                          choices = c(Head = "head",
                                      All = "all"),
                          selected = "head")
             
             
           ),
           
           #main panel to display outputs
           mainPanel(
             
             #output-- data file
             dataTableOutput('contents')
             
           )
         )
),
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
#point estimate line plot
tabPanel("Point Estimate Line Plot",
         pageWithSidebar(
           headerPanel('Point Estimate Line Plot'),
           sidebarPanel(
             
             #drop down menu inputs
             selectInput('xcol','X Variable',""),
             selectInput('ycol','Y Variable',""),
             sliderInput("slider_lineplot", label = h3("Select range of samples by Column ID"), min = 0, 
                         max = 20, value = 1),
             selectInput("specimen","Select Specimen Type column",""),
             selectInput("LCI","Lower Confidence Interval(LCI):",""),
             selectInput("UCI","Upper Confidence Interval(UCI):",""),
             
             #label inputs
             textInput("title_lineplot",label="Plot Title",value="Enter text..."),
             textInput("xlabel_lineplot",label="x-axis label",value="Enter text..."),
             textInput("ylabel_lineplot",label="y-axis label",value="Enter text..."),
             numericInput("referenceline","Reference value",0.95,min=0,max=1,step=0.01)
           ),
           mainPanel(
             plotOutput('lineplot'),
             br(),
             br(),
             dataTableOutput('lineplot_table')
             
           )
         )
         
),
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------     
#concentric pie chart
tabPanel("Concentric Pie Chart",
         pageWithSidebar(
           headerPanel('Pie Chart'),
           sidebarPanel(
             #label inputs
             textInput("title",label="Plot Title",value="Enter text..."),
             sliderInput("slider_piechart", label = h3("Select Column ID"), min = 0, 
                         max = 20, value = 1),
             selectInput('fill','Select Result Column',""),
             selectInput('upperbound','Select YMAX Column',""),
             selectInput('lowerbound','Select YMIN Column',""),
             selectInput('ref','Select Type Column',"")
           ),
           mainPanel(
             plotOutput('piechart'),
             dataTableOutput('piechart_table')
           )
         )
         
),
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------    

)
)

#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Define server logic required to read file, and display all the different plots

server<- function(input, output,session) {

added "session" because updateSelectInput requires it

data <- reactive({
req(input$file1) ## ?req # require that the input is available

inFile <- input$file1 

# tested with a following dataset: write.csv(mtcars, "mtcars.csv")
# and                              write.csv(iris, "iris.csv")
df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
               quote = input$quote)

#augment data set. Add Sensitivity(PPA), Specificity(NPA), False Positive Rate(1-specificity), and 95% confidence intervals for PPA and NPA


#Tp = true positive, Fp = false positive, Fn = false negative, Tn = True negative
#add PPA and NPA
df$PPA <- round((df$TP)/(df$TP+df$FN),3)   #sensitivity = Tp/(Tp+Fn)
df$NPA <- round((df$TN)/(df$TN+df$FP),3)      #specificity = Tn/(Tn+Fp)

#----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#add wilson confidence intervals
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#Sensitivity(PPA) calculations-- first calculate Q1, Q2, Q3 quantiles
Q1_se <- (2*df$TP)+3.84

FNR <- (df$FN)/(df$TP+df$FN)   #false negative rate(FNR) = Fn/(Fn+Tp)
Q2_se <- 1.96 * sqrt(3.84 + (4*df$TP*FNR))

Q3_se <- (2*(df$TP+df$FN))+7.68

#95% confidence intervals

#lower bound CI(LCI) and upper bound CI(UCI) for PPA
df$PPA_LCI <- round((Q1_se-Q2_se)/(Q3_se),3)
df$PPA_UCI <- round((Q1_se+Q2_se)/(Q3_se),3)
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#Specificity(NPA)calculations-- first calculate Q1, Q2, Q3 quantiles
Q1_sp <- (2*df$TN)+3.84

TNR <- (df$TN)/(df$TN+df$FP)   #false negative rate(FNR) = Fn/(Fn+Tp)
Q2_sp <- 1.96 * sqrt(3.84 + (4*df$FP*TNR))

Q3_sp <- (2*(df$FP+df$TN))+7.68

#95% confidence intervals

#lower bound CI(LCI) and upper bound CI(UCI) for NPA
df$NPA_LCI <- round((Q1_sp-Q2_sp)/(Q3_sp),3)
df$NPA_UCI <- round((Q1_sp+Q2_sp)/(Q3_sp),3)


df <- as.data.frame(df)
#datalist <- list(df=df, PPA=df$PPA, NPA=df$NPA, PPA_LCI=df$PPA_LCI, PPA_UCI=df$PPA_UCI,NPA_LCI=df$NPA_LCI,NPA_UCI=df$NPA_UCI,ColumnID=df$`Column ID`)
#datalist

return(df)

})

#---------------------------------------------------------------
lineplot_dataframe <- reactive({

df_lineplot <- filter(df,df$`Column ID`==1:input$slider_lineplot)
#df_lineplot <- filter(datalist$df,datalist$ColumnID==1:input$slider_lineplot)
#line plot create data frame
df2_lineplot <- data.frame(matrix(nrow=dim(df_lineplot)[1],ncol=7))
colnames(df2_lineplot) <- c("SpecimenType","PPA","NPA","PPA_upper","PPA_lower","NPA_upper","NPA_lower")

df2_lineplot$SpecimenType <- df_lineplot$`Specimen Type`

df2_lineplot$PPA<- round(df_lineplot$PPA,3)
df2_lineplot$NPA<- round(df_lineplot$NPA,3)

df2_lineplot$PPA_lower <- round(df_lineplot$PPA_LCI,3)
df2_lineplot$PPA_upper <- round(df_lineplot$PPA_UCI,3)

df2_lineplot$NPA_lower <- round(df_lineplot$NPA_LCI,3)
df2_lineplot$NPA_upper <- round(df_lineplot$NPA_UCI,3)

df2_lineplot <- as.data.frame(df2_lineplot)

#update select input for line plot
updateSelectInput(session, inputId = 'xcol', label = 'X Variable',
                  choices = names(df2_lineplot), selected = "")
updateSelectInput(session, inputId = 'ycol', label = 'Y Variable',
                  choices = names(df2_lineplot), selected = "")
updateSelectInput(session, inputId = 'specimen', label = 'Select Specimen Type column',
                  choices = names(df2_lineplot), selected = "")
updateSelectInput(session, inputId = 'LCI', label = 'Lower Confidence Interval(LCI):',
                  choices = names(df2_lineplot), selected = "")
updateSelectInput(session, inputId = 'UCI', label = 'Upper Confidence Interval(UCI):',
                  choices = names(df2_lineplot), selected = "")

return(df2_lineplot)

})
#---------------------------------------------------------------
#create reactive table for pie chart information
PieData_extracted <- reactive({

#PF <- filter(select(df1,6:9),df$`Column ID`==input$slider_piechart)
PF <- filter(select(df,1,6:9),df$`Column ID`==input$slider_piechart)

PF2 <- data.frame(matrix(nrow=4, ncol=7))
colnames(PF2) <- c("Type","Result","Result_transformed","Value","Percent","YMIN","YMAX")
PF2$Result <- colnames(PF)[2:5]
PF2$Value <- c(PF$TP,PF$FN,PF$TN,PF$FP)
PF2$Result_transformed <- c(0,0,1,1)
PF2$Type <- ifelse(PF2$Result_transformed==0,"Reference Positive","Reference Negative")

#percentage calculations
PF2$Percent <- round((PF2$Value/sum(PF2$Value))*100,2)
PF2$YMAX <- cumsum(PF2$Percent)
PF2$YMIN <- c(0,cumsum(PF2$Percent)[1:3])

#update select input for pie chart
updateSelectInput(session, inputId = 'fill', label = 'Select result(i.e TP, FN)',
                  choices = names(PF2)[2], selected = "")
updateSelectInput(session, inputId = 'upperbound', label = 'Select YMAX Column',
                  choices = names(PF2)[7], selected = "")
updateSelectInput(session, inputId = 'lowerbound', label = 'Select YMIN Column',
                  choices = names(PF2)[6], selected = "")
updateSelectInput(session, inputId = 'ref', label = 'Select Reference Column',
                  choices = names(PF2)[1], selected = "")


return(PF2)

})

For the lineplot and PF data frames, I'm calling df, the data frame which shows the raw data initially uploaded. I'm wondering if there is a different syntax to call the data.

What is this line trying to do? Try putting dplyr::filter and dplyr::select.

PF <- filter(select(df,1,6:9),df$`Column ID`==input$slider_piechart)

I would write it as

PF <- df %>%
    dplyr::select(1, 6:9) %>%
    dplyr::filter(`Column ID` == input$slider_piechart)

Im trying to:

  1. access the data table from the reactive data frame, data()
  2. select specific rows within this reactive data frame, hence the Column ID = input$slider_piechart. The pie chart will be constructed based on the row # that is selected in the numerical sliding bar input.

Hi,

Just based on the issue at hand, namely having the same file being filtered differently for multiple plots, I came up with this toy example:

library("shiny")


ui <- fluidPage(
  sidebarLayout(
    
    sidebarPanel(
      fileInput("myFile", "Choose .csv file")
    
      ),
    
    mainPanel(
      
      plotOutput("plot1"),
      plotOutput("plot2")
      
    )
  )
  
  
)

server <- function(input, output, session) {
  
  write.csv(data.frame(id = 1:100, value = runif(100)), "myData.csv", row.names = F)
  myData = reactive({read.csv(req(input$myFile$datapath))})

  plot1Data = reactive({
    filteredData = myData()[1:50,]
    filteredData = filteredData + 10
  })
  
  plot2Data = reactive({
    filteredData = myData()[myData()$value > 0.5,]
  })
  
  output$plot1 = renderPlot({
    plot(plot1Data())
  })
  
  output$plot2 = renderPlot({
    hist(plot2Data()$value)
  })
  
  
  
}

shinyApp(ui, server)

*The app generates a dummy datafile called myData.csv which will be in the app's home directory.

Play with it and see if it helps.
Grtz,
PJ