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

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.