ShinyR : Unexpected result when exporting inputs

微笑、不失礼 提交于 2019-12-13 04:28:27

问题


following this post: (ShinyR : Insert user inputs in a database for further use), I found a solution to my problem, strongly inspired by this shiny app (https://deanattali.com/2015/06/14/mimicking-google-form-shiny/).

I managed to get the main result I wanted (a database combining my observations and the results of the user of the app). Nonetheless I now have two new questions:

First, how is it possible when looking at my code (complete version at the end of the post). Here are the lines from the server part of the code use to extract the inputs. Two variables are created

  • Udata with only the inputs from the user, which is to be saved as a single file (%s_%s.csv).
  • Mdata which is the combination of the inputs (Udata) and the database (DB_Nonames), also to be saved as a single file (%s_%s_Merged.csv).

The problem is encountered here: only one file is saved (%s_%s.csv) BUT it is composed not only of the inputs from the user (Udata) but also of the complete database (DB_Nonames). The error message is that "argument "Mdata" is missing, with no default", like it doesn't exist, however it seems that somehow Udata got merged with the database while still being called Udata (even though it's not suppose to).

formData <- reactive({
  Udata <- sapply(fieldsAll, function(x) input[[x]]) #fieldsAll is an array with all the fields completed by the user
  Udata <- c(Udata, PSS = (input$SSS/input$SBL)) #Test to see if I can add a new field using inputs
  Udata <- t(Udata) #transposition to get a line 
  Mdata <- rbind(DB_NoNames,Udata) #Merge of my database and the inputs from the user
})

saveData <- function(Udata,Mdata) {
  fileName <- sprintf("%s_%s.csv", #First a .csv file with only the inputs from the user
                      humanTime(),
                      digest::digest(Udata)) #To get a unique fileName for each user using time of submit and values of the inputs
  fileName2 <- sprintf("%s_%s_Merged.csv", #Second a .csv file with the database + the inputs
                      humanTime(),
                      digest::digest(Udata))
  write.csv(x = Udata, file = file.path(responsesDir, fileName),
            row.names = c(indnames))
  write.csv(x = Mdata, file = file.path(responsesDir, fileName2),
            row.names = c(indnames))
}

Second, after understanding this witchcraft, how could it be fixed?

Thanks a lot to all, if I'm not clear please let me know and I'll try an other explanation.

Here is the complete code (most of it comes from https://deanattali.com/2015/06/14/mimicking-google-form-shiny/ which as detailed explainations)

#############################################
DB <- read.csv2("~/filepath/DB.csv", row.names = 1, sep=",", dec=".")
DB_NoNames <- DB
rownames(DB_NoNames) <- NULL
indnames <- c(rownames(DB),"USER")

fieldsMandatory <- c("SBL", "SSS")
labelMandatory <- function(label) {
tagList(label, span("*", class = "mandatory_star")
)}

appCSS <- ".mandatory_star { color: red; }
#error { color: red; }"

fieldsAll <- c("AGE", "SBL", "SSS")

responsesDir <- file.path("~/filepath/responses")
responsesDBDir <- file.path("~/filepath/ResponsesAndDb")

epochTime <- function() {
as.integer(Sys.time())
}

humanTime <- function() format(Sys.time(), "%Y%m%d-%H%M%OS")

loadData <- function() {
  files <- list.files(file.path(responsesDir), full.names = TRUE)
  data <- lapply(files, read.csv, stringsAsFactors = FALSE)
  data <- dplyr::rbind_all(data)
  data
}

adminUsers <- c("admin")

#############################################

shinyApp(

#############################################

  ui = fluidPage(
shinyjs::useShinyjs(),
shinyjs::inlineCSS(appCSS),
titlePanel("Users'data"),

uiOutput("adminPanelContainer"),    

div(
  id = "form",

  numericInput("AGE", "Age de la ferme", value = 1, min=0),
  numericInput("SBL", labelMandatory("Surface brute en légumes (ha)"), value = 1, min=0),
  numericInput("SSS", labelMandatory("Surface sous serre (ha)"), value = 0.3, min=0),
  actionButton("submit", "Valider", class = "btn-primary"),
  shinyjs::hidden(
    span(id = "submit_msg", "Submitting..."),
    div(id = "error",
        div(br(), tags$b("Error: "), span(id = "error_msg"))
    )
  )
),

shinyjs::hidden(
  div(
    id = "thankyou_msg",
    h3("Merci, vos données ont été enregistrées avec succès. Vous pouvez maintenant utiliser l'outil ou enregistrer de nouvelles données"),
    actionLink("submit_another", "Enregistrer de nouvelles données")
  )
)  

  ),

#############################################

  server = function(input, output, session) {
observe({
  mandatoryFilled <-
    vapply(fieldsMandatory,
           function(x) {
             !is.null(input[[x]]) && input[[x]] != ""
           },
           logical(1))
  mandatoryFilled <- all(mandatoryFilled)

  shinyjs::toggleState(id = "submit", condition = mandatoryFilled)
})

formData <- reactive({
  Udata <- sapply(fieldsAll, function(x) input[[x]])
  Udata <- c(Udata, PSS = (input$SSS/input$SBL))
  Udata <- t(Udata)
  Mdata <- rbind(DB_NoNames,Udata)
})

saveData <- function(Udata,Mdata) {
  fileName <- sprintf("%s_%s.csv",
                      humanTime(),
                      digest::digest(Udata))
  fileName2 <- sprintf("%s_%s_Merged.csv",
                      humanTime(),
                      digest::digest(Udata))
  write.csv(x = Udata, file = file.path(responsesDir, fileName),
            row.names = c(indnames))
 # write.csv(x = Mdata, file = file.path(responsesDir, fileName2),
 #           row.names = c(indnames))
}

# action to take when submit button is pressed
observeEvent(input$submit, {
  shinyjs::disable("submit")
  shinyjs::show("submit_msg")
  shinyjs::hide("error")

  tryCatch({
    saveData(formData())
    shinyjs::reset("form")
    shinyjs::hide("form")
    shinyjs::show("thankyou_msg")
  },
  error = function(err) {
    shinyjs::html("error_msg", err$message)
    shinyjs::show(id = "error", anim = TRUE, animType = "fade")
  },
  finally = {
    shinyjs::enable("submit")
    shinyjs::hide("submit_msg")
  })
})

observeEvent(input$submit_another, {
  shinyjs::show("form")
  shinyjs::hide("thankyou_msg")
}) 

output$responsesTable <- DT::renderDataTable(
  loadData(),
  rownames = FALSE,
  options = list(searching = FALSE, lengthChange = FALSE)
) 

output$downloadBtn <- downloadHandler(
  filename = function() { 
    sprintf("mimic-google-form_%s.csv", humanTime())
  },
  content = function(file) {
    write.csv(loadData(), file, row.names = FALSE)
  }
)

output$adminPanelContainer <- renderUI({
  if (!isAdmin()) return()

  wellPanel(
    h2("Previous responses (only visible to admins)"),
    downloadButton("downloadBtn", "Download responses"), br(), br(),
    DT::dataTableOutput("responsesTable")
  )
})

isAdmin <- reactive({
  is.null(session$user) || session$user %in% adminUsers
})
  })

来源:https://stackoverflow.com/questions/55209822/shinyr-unexpected-result-when-exporting-inputs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!