1
votes

I am writing my first Shiny application. The gist of the code is to read in a csv file, the user answers some inputs from the app, and those data are appended to the csv file. The intent is that this file is kept day-to-day and the app updates the contents. This file will then be used later for analysis.

My app does this successfully when opened the first time. However, when the session is closed and then reopened for later use (imagine closing the app before lunch and then reopening after lunch) the CSV file can no longer be appended due to "Error: names do not match previous names"

I first have an "empty" .csv with just a header row with three columns (A, B, C) called log.csv.

I then use the following code to create the Shiny App.

library(shiny)

ui <- fluidPage(

  # Application title
  titlePanel("My 1st App"),

  #Enter Agent
  selectInput(inputId = "a", "A", c("Choose one" = "","A1", "A2", "A3"),
         multiple = FALSE, selectize = TRUE, width = NULL, size = NULL),

  #Enter Concentration
  numericInput(inputId = "b", "Favorite Number", NULL, min = 0, max = NA),

  #Enter Detection
  radioButtons(inputId = "c", "Are you Happy Y/N", c("Y", "N")),
  actionButton(inputId = "submit", "Submit", icon = NULL, width = NULL),
  verbatimTextOutput("summary"),

  log <- read.table("V:\\My\\Path\\log.csv",sep=",",header=T)

)


server <- function(input, output) {
    data <- eventReactive(input$submit, {         
        t <- cbind(input$agent,input$conc, input$detect)
        names(t) <- c("A","B","C")
        t         
  })


     output$summary <- renderPrint({data() #outputs data in allotted field.

       write.table(rbind(log,data()), file="V:\\My\\Path\\log.csv", sep=",",
                             col.names= FALSE, row.names=F, append = T)
      }) 

}
shinyApp(ui = ui, server = server)'

The log.csv is the original blank file with the headers A, B, C.

The error obviously occurs because the names in the log dataframe do not match with the names from the reactive data().

In plain R, I can fix the issue with this code:

log <- data.frame(read.table("V:\\My\\Path\\log.csv",sep=",",header=T))
names(log)

a <- c("A1", "A3", "A2")
b <- c(0,1,2)
c <- c("y","n","n")
t <- data.frame(cbind(a,b, c))
names(t) <- c("A","B","C")
t
rbind(log,t)

So, I tried to use this logic and updated the reactive data statement in the server section (above code already reflects this update). It still doesn't work when the app is closed and reopened. I don't know what about having previous data filled in the log makes the names not match up.

I appreciate any help. I've struggled for days and have researched many posts. This is my first post so please forgive any etiquette that I didn't follow correctly. However, I'd be glad to be gently nudged on more appropriate ways to post or ask questions.

2

2 Answers

2
votes

Maybe you can try with observeEvent if you don't need an output in your app. (I changed a bit the code to make it easier for me but the idea is the same).

library(shiny)
path <- "your path"
log <- read.csv(paste0(path,"log.csv"))

ui <- fluidPage(

  # Application title
  titlePanel("My 1st App"),

  #Enter Agent
  selectInput(inputId = "a", "A", c("Choose one" = "","A1", "A2", "A3"),
          multiple = FALSE, selectize = TRUE, width = NULL, size = NULL),

  #Enter Concentration
  numericInput(inputId = "b", "Favorite Number", NULL, min = 0, max = NA),

  #Enter Detection
  radioButtons(inputId = "c", "Are you Happy Y/N", c("Y", "N")),
  actionButton(inputId = "submit", "Submit", icon = NULL, width = NULL)
)

server <- function(input, output) {

  observeEvent(input$submit, {
    t <- data.frame(A= input$a, B = input$b, C= input$c)
    data <- rbind(log,t)
    write.csv(data, file=paste0(path,"log.csv"),row.names=F)
  })
}

shinyApp(ui = ui, server = server)
1
votes

For anybody else who may follow I'm posting the final solution. This could not have been done without D. Alburez' reply. I modified his code just a bit to get the answer I was looking for.

library(shiny)
path <- "your path"
log <- read.csv(paste0(path,"log.csv"))

ui <- fluidPage(

  # Application title
  titlePanel("My 1st App"),

  #Enter Agent
  selectInput(inputId = "a", "A", c("Choose one" = "","A1", "A2", "A3"),
          multiple = FALSE, selectize = TRUE, width = NULL, size = NULL),

  #Enter Concentration
  numericInput(inputId = "b", "Favorite Number", NULL, min = 0, max = NA),

  #Enter Detection
  radioButtons(inputId = "c", "Are you Happy Y/N", c("Y", "N")),
  actionButton(inputId = "submit", "Submit", icon = NULL, width = NULL)
)

server <- function(input, output) {

  observeEvent(input$submit, {
    data <- data.frame(A= input$a, B = input$b, C= input$c)
    write.table(data, file=paste0(path,"log.csv"), sep=",",
                col.names= FALSE, row.names=F, append = T)
  })
}

shinyApp(ui = ui, server = server)

Thanks again D! Now off to the next problem....