Shinyapp.io deployment fails on rmarkdown code

Hello all!

I'm having some trouble in deploying my shiny app to shinyapps.io. The basics of my app involve having the user upload a csv, which then gets formatted and is available for download through an rmarkdown latex document. Though this app works locally, I keep receiving the following error in my server logs:

Warning: Error in $: $ operator is invalid for atomic vectors

This error is present in my rmarkdown code, which I was under the impression didn't run until after the download button was pressed. Since the rmarkdown code depends on the file input, many of the variables in the offending code chunk don't exist or are null before this.

Below is the code from the offending code chunk:

file2 <- as.data.frame(params$data2)
filehom <- as.data.frame(params$data3)

colnames(filehom) <- as.character(unlist(filehom[1,]))
filehom <- filehom[-1,]
check <- FALSE

if(!is.null(labcode) & !is.null(file2$`CAM CODE`))
{
  ###Logical check if CAM code is included in SampleData
  if(labcode %in% file2$`CAM CODE`)
  {
    check <- TRUE
    index <- grep(labcode,file2$`CAM CODE`)
    cols <- colnames(file2)
    ###Isolate individual test data frames
    if(TRUE)
    {
      infodf <- file2[index,cols[3:4]]
      dosdf <- file2[index,cols[5:6]]
      dendf <- file2[index,cols[7]]
      ph2df <- file2[index,cols[8:9]]
      coldf <- file2[index,cols[10:12]]
      brxdf <- file2[index,cols[13]]
      gasdf <- file2[index,cols[14:15]]
      turdf <- file2[index,cols[16:18]]
      phsdf <- file2[index,cols[19]]
    }
    
    ###Pass/Fail Status
    if(TRUE)
    {
      doslimit <- c(250,2.5)
      dospass <- as.data.frame(matrix(c(dosdf$`SERVING MASS (g)`<(doslimit[1]+(doslimit[1]*0.1)) & dosdf$`SERVING MASS (g)`>(doslimit[1]-(doslimit[1]*0.1)),dosdf$`SERVING DOSE (mg/serv)`<(doslimit[2]+(doslimit[2]*0.1)) & dosdf$`SERVING DOSE (mg/serv)`>(doslimit[2]-(doslimit[2]*0.1))),nrow=1,ncol=2))
      colnames(dospass) <- cols[5:6]
      phlimit <- 4.5
      ph2pass <- c(as.numeric(substr(ph2df$'pH DEGASSED',0,3)) < phlimit & as.numeric(substr(ph2df$'pH CARBONATED',0,3))< phlimit)
      denpass <- TRUE
      colpass <- TRUE
      gaspass <- TRUE
      brxpass <- TRUE
      vispass <- TRUE
      turpass <- TRUE
      phspass <- TRUE
    }
    
    ###Update Inclusion Criteria
    if(TRUE)
    {
      if(!is.null(infodf$DATE) | !is.null(infodf$`# CANS PULLED`))
      {
        include[grep("INFO",include$TestCode),4] <- TRUE
      }
      if(!is.null(dosdf$`SERVING MASS (g)`) | !is.null(dosdf$`SERVING DOSE (mg/serv)`))
      {
        include[grep("DOS",include$TestCode),4] <- TRUE
      }
      if(!is.null(dendf))
      {
        include[grep("DEN",include$TestCode),4] <- TRUE
      }
      if(!is.null(ph2df$`pH DEGASSED`) | !is.null(ph2df$`pH CARBONATED`))
      {
        include[grep("PH",include$TestCode),4] <- TRUE
      }
      if(!is.null(coldf$`COLOR L`) | !is.null(coldf$`COLOR A`) | !is.null(coldf$`COLOR B`))
      {
        include[grep("COL",include$TestCode),4] <- TRUE
      }
      if(!is.null(brxdf))
      {
        include[grep("BRIX",include$TestCode),4] <- TRUE
      }
      if(!is.null(gasdf$`CO2 (Volumes of CO2)`) | !is.null(gasdf$`O2 (ppb)`))
      {
        include[grep("GAS",include$TestCode),4] <- TRUE
      }
      if(!is.null(turdf$`TURBIDITY (%T)`) | !is.null(turdf$CLARITY) | !is.null(turdf$CLOUDINESS))
      {
        include[grep("TUR",include$TestCode),4] <- TRUE
      }
      if(!is.null(phsdf))
      {
        include[grep("PSP",include$TestCode),4] <- TRUE
      }
      
    }
  }
}

if(!is.null(labcode) & !is.null(filehom$`CAM CODE`))
{
  ###Logical check if CAM code is included in Homogeneity
  if(labcode %in% filehom$`CAM CODE`)
  {
    index <- grep(labcode,filehom$`CAM CODE`)
    cols <- colnames(filehom)
    ###Isolate Concentration and Mass data frames
    if(TRUE)
    {
      homconcdf <- filehom[index,c(2,4,6,8,10,12,14,16,18,20)]
      homservdf <- filehom[index,c(3,5,7,9,11,13,15,17,19,21)]
    }
    
    ###Pass/Fail Status
    if(TRUE)
    {
      totmgperg <- c()
      totgrams <- c()
      perserv <- c()
      hompass <- NULL
      for(i in 1:ncol(homconcdf))
      {
        totmgperg <- c(totmgperg,unlist(homconcdf[,i]))
        totgrams <- c(totgrams,unlist(homservdf[,i]))
        perserv <- c(perserv,unlist(homconcdf[,i])*unlist(homservdf[,i]))
      }
      perserv <- round(perserv,2)
      perservrsd <- round((sd(perserv)/mean(perserv))*100,2)
      
      if(perservrsd < 15)
      {
        hompass <- TRUE
      }
      else
      {
        hompass <- FALSE
      }
    }
    
    ###Update Inclusion Criteria
    if(TRUE)
    {
      if(!is.null(hompass))
      {
        include[grep("HOM",include$TestCode),4] <- TRUE
      }
    }
  }
}

Since the code works just fine locally, I'm confident this isn't a case of referencing the wrong data type, and think it has something more to do with how the app is packaged for deployment.

Can anyone offer any advice in handling this? Thank you!