How to add lines in a data.frame and or table in shinyserver?

Asked

Viewed 581 times

1

Hello, good night, good night! I’m trying to sort some things out by shiny, but I ran into a problem, I need to create a data.frame, where I am able to add lines of information, without being doing the logistics of using write.table() vs read.table.

library(shiny)



ui<-fluidPage(
sidebarPanel(
fluidRow(
selectInput("INPUT",  label="Entrada:"  ,choices=list("",1,2,3,4,5,6,7)),
selectInput("NOMEIPT", label="Nome:", choices=list("","Área","Comprimento","Largura")),
selectInput("COLOUR", label="Cor:",  choices=list("","black","white","red","green","blue","brown","yellow")),
actionButton("ADDIN",label="adicionar"))),
            mainPanel(fluidPage(
              fluidRow(tableOutput("dados")))))

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

  counter <- reactiveValues(countervalue = 0) # tentei gerar um valor reativo, para criar vários data.frames
    observeEvent(input$ADDIN,{

counter$countervalue <- counter$countervalue + 1 })

  eventReactive(input$ADDIN,{
    # nesse caso deveria a cada vez que eu selecionace as três, opções, e clicasse no botão "Adicionar"
    # ele deveria gerar um data.frame: df1<-data.frame(iten=..cor=..nome=..) para cada click df2...df3...df4..
    eval(parse(text=paste("df",as.numeric(input$INPUT),"<-data.frame(iten=",as.numeric(input$INPUT),',cor="',input$COLOUR,'",nome=',input$NOMEIPT,")",sep="")))
      })


  # depois seria necessário apenas juntar esses data.frame usando o rbind, ou rbind.data.frame, não sei a diferença dos dois.
  # porém , eu não sei porque cargas d'água os data.frames não ficam armazenados... até pensei em colocar eles dentro da sessão, porém como eles usar entradas reativas
  # "input$.....", não iria funcionar.....

  DFrame<-eventReactive(input$ADDIN,{
    eval(parse(text=paste(c("rbind(",rep("",counter$countervalue-1)),"df",1:counter$countervalue,c(rep(",",counter$countervalue-1),")"),sep="")))

  })


  output$dados<-renderTable({DFrame()
  })

}

shinyApp(ui,server1)

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

# Também tentei criar uum objeto reativo, e acrescentar a ele um data.frame vazio:

server2 <- function(session,input, output) {
  DT<-reactiveValues(DT=NULL)


  observeEvent(input$ADDIN,{

    DT$DT<-data.frame(iten=NULL,cor=NULL,nome=NULL)
  })

  DFrame<-eventReactive(input$ADDIN,{

  rbind.data.frame(DT$DT,data.frame(iten=as.numeric(input$INPUT),cor=input$COLOUR,nome=input$NOMEIPT))
 })

 output$dados<-renderTable({DFrame()})

}

shinyApp(ui,server2)
#---------------------------------------------------------------------------------------
# tentei dessa forma adicionando linhas ao data.frame vazio

  server3 <- function(session,input, output) {
    DT<-reactiveValues(DT=NULL)


    observeEvent(input$ADDIN,{

      DT$DT<-data.frame(iten="",cor="",nome="")
    })

eventReactive(input$ADDIN,{

  DT$DT[as.numeric(input$INPUT),]<-data.frame(iten=as.numeric(input$INPUT),cor=input$COLOUR,nome=input$NOMEIPT)

})

output$dados<-renderTable({DT$DT})

  }



  shinyApp(ui,server3)

What I need is that he manages one data.frame(iten=..,cor=..,nome=..), and as I select the options and click add, it stores and load the information, and each change of options, by clicking add, it adds a new line to the data.frame with the new information... I need this because I will use as the data.frame items to manage, the names and colors I will use in the kml files I will load.... so did not want to be reworked table by write.table(), and read.table()... because each new file would generate a new table!

1 answer

2


INTRODUCTION

I will present the solution of the problem using the reactValues. Meanwhile read the considerations I will make about this solution right away.

SOLUTION

The solution is this:

  1. create an empty data.frame in the app file. R, outside the ui and server.
  2. create a reactValue for the data.frame created.
  3. update the data.frame from the inputs whenever the button is clicked

Here’s the full app code. R

library(shiny)

## Cria data.frame vazio só para começar
df <- data.frame(Entrada=character(),
                 Nome=character(), 
                 Cor=character(), 
                 stringsAsFactors=FALSE)

## Interface que não foi alterada
ui <- fluidPage(
          sidebarPanel(
            fluidRow(
              selectInput("INPUT",  label="Entrada:"  ,choices=list("",1,2,3,4,5,6,7)),
              selectInput("NOMEIPT", label="Nome:", choices=list("","Área","Comprimento","Largura")),
              selectInput("COLOUR", label="Cor:",  choices=list("","black","white","red","green","blue","brown","yellow")),
              actionButton("ADDIN",label="adicionar"))),
          mainPanel(fluidPage(
            fluidRow(tableOutput("dados")))))

## Única alterada por mim
server <- function(session,input, output) {

  ## Uso do reactvalues para armazenar os dados
  values <- reactiveValues(df_data = df)

  ## Sempre que houver um toque no botão uma nova linha é adicionada
  observeEvent(input$ADDIN, {
    nova_linha <- data.frame(Entrada=input$INPUT, Nome=input$NOMEIPT, Cor=input$COLOUR)
    values$df_data <- rbind(values$df_data, nova_linha)
  })

  output$dados<-renderTable({ values$df_data
  })

}

shinyApp(ui,server)

the behavior you will get is as follows:

inserir a descrição da imagem aqui

CONSIDERATIONS

From the web programming point of view the problem you are facing is the problem of managing the application state. Note that a good application should be uncoupled from the data. The ideal would you create a way to store the data needed to select the future files that you will download in the selection of the inputs itself and not store in a data.frame. The shape ideal to store the app data throughout sessions is through a database management system, which could be up to Sqlite3. However, in this case, the data would be permanently stored, which I believe was not his goal. I did not post this solution because it is outside the scope of the question and I believe that would not be the ideal solution to your problem.

  • Thank you very much Flavio Barros, broke me was a tree!!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.