web-dev-qa-db-fra.com

Entrée de données via shinyTable dans l'application R shiny

Je veux créer une application brillante qui obtient les données de la matrice en entrée et renvoie une table basée sur certaines opérations sur celle-ci en sortie. Par recherche, je trouve que le package ShinyTable pourrait être utile. J'ai essayé ci-dessous des codes brillants mais l'application de résultat apparaît grisée et sans résultat.

library(shinyTable)
shiny::runApp(list(
  ui=pageWithSidebar(
    headerPanel('Simple matrixInput')
    ,
    sidebarPanel(
      htable("tbl")
      ,
      submitButton("OK")
    )
    ,
    mainPanel(

      tableOutput(outputId = 'table.output')
    ))
  ,
  server=function(input, output){
    output$table.output <- renderTable({
      input$tbl^2
    }
    , sanitize.text.function = function(x) x 
    )
  }
))

ne idée?

21
Mahmoud

Le package shinyTable a été considérablement amélioré dans le rhandsontable package .

Voici une fonction minimale qui prend un bloc de données et exécute une application brillante permettant de le modifier et de l'enregistrer dans un fichier rds:

library(rhandsontable)
library(shiny)

editTable <- function(DF, outdir=getwd(), outfilename="table"){
  ui <- shinyUI(fluidPage(

    titlePanel("Edit and save a table"),
    sidebarLayout(
      sidebarPanel(
        helpText("Shiny app based on an example given in the rhandsontable package.", 
                 "Right-click on the table to delete/insert rows.", 
                 "Double-click on a cell to edit"),

        wellPanel(
          h3("Table options"),
          radioButtons("useType", "Use Data Types", c("TRUE", "FALSE"))
        ),
        br(), 

        wellPanel(
          h3("Save"), 
          actionButton("save", "Save table")
        )        

      ),

      mainPanel(

        rHandsontableOutput("hot")

      )
    )
  ))

  server <- shinyServer(function(input, output) {

    values <- reactiveValues()

    ## Handsontable
    observe({
      if (!is.null(input$hot)) {
        DF = hot_to_r(input$hot)
      } else {
        if (is.null(values[["DF"]]))
          DF <- DF
        else
          DF <- values[["DF"]]
      }
      values[["DF"]] <- DF
    })

    output$hot <- renderRHandsontable({
      DF <- values[["DF"]]
      if (!is.null(DF))
        rhandsontable(DF, useTypes = as.logical(input$useType), stretchH = "all")
    })

    ## Save 
    observeEvent(input$save, {
      finalDF <- isolate(values[["DF"]])
      saveRDS(finalDF, file=file.path(outdir, sprintf("%s.rds", outfilename)))
    })

  })

  ## run app 
  runApp(list(ui=ui, server=server))
  return(invisible())
}

Par exemple, prenez le bloc de données suivant:

> ( DF <- data.frame(Value = 1:10, Status = TRUE, Name = LETTERS[1:10],
                    Date = seq(from = Sys.Date(), by = "days", length.out = 10),
                    stringsAsFactors = FALSE) )
   Value Status Name       Date
1      1   TRUE    A 2016-08-15
2      2   TRUE    B 2016-08-16
3      3   TRUE    C 2016-08-17
4      4   TRUE    D 2016-08-18
5      5   TRUE    E 2016-08-19
6      6   TRUE    F 2016-08-20
7      7   TRUE    G 2016-08-21
8      8   TRUE    H 2016-08-22
9      9   TRUE    I 2016-08-23
10    10   TRUE    J 2016-08-24

Lancez l'application et amusez-vous (surtout avec les calendriers ^^):

enter image description here

Modifiez le Handsontable:

enter image description here

Cliquez sur le bouton Enregistrer. Il enregistre la table dans le fichier table.rds. Lisez-le ensuite dans R:

> readRDS("table.rds")
   Value Status    Name       Date
1   1000  FALSE Mahmoud 2016-01-01
2   2000  FALSE       B 2016-08-16
3      3  FALSE       C 2016-08-17
4      4   TRUE       D 2016-08-18
5      5   TRUE       E 2016-08-19
6      6   TRUE       F 2016-08-20
7      7   TRUE       G 2016-08-21
8      8   TRUE       H 2016-08-22
9      9   TRUE       I 2016-08-23
10    10   TRUE       J 2016-08-24
21
Stéphane Laurent

Si vous cherchez une solution permettant aux utilisateurs de saisir leurs données matricielles comme dans Excel, vous pouvez probablement jeter un œil au package "shinySky" et plus spécifiquement à son composant "Handsontable Input/Output". L'adresse Web pertinente est: https://github.com/AnalytixWare/ShinySky .

Une autre solution similaire serait le package shinyTable. Vous pouvez trouver plus d'informations sur https://github.com/trestletech/shinyTable

6
Christos

Vous pouvez utiliser hotable("matrixTable") à partir du shinysky package .

library(shiny, shinysky)
shinyApp(
  ui     = shinyUI (wellPanel(hotable("matrixTable"),hotable("resultTable"))),

  server = shinyServer (function(input, output) {
    A = matrix(c(1:6), nrow=2) # init - input matrix A
    output$matrixTable <- renderHotable({data.frame(A)}, readOnly = FALSE)

    R = matrix(rep(0,6), nrow=2) # init - result matrix R
    output$resultTable <- renderHotable({data.frame(R)}, readOnly = TRUE)

    observe({  # process matrix
      df <- hot.to.df(input$matrixTable)
      if(!is.null(df)) {    # ensure data frame from table exists
        B = data.matrix(df) # ensure its numeric
        R = B^2             # some matrix operation
        output$resultTable <- renderHotable({data.frame(R)})
      }
    }) # end of observe
  }) # end of server
)

Dans l'interface utilisateur ui l'entrée "matrixTable" et le "resultTable" sont visualisés. server initialise ces tables, de sorte que matrixTable peut être édité. Cela signifie que vous pouvez copier et coller vos données depuis Excel ou modifier les valeurs manuellement. La fonction observe est activée, chaque fois qu'un changement est remarqué dans l'entrée matrixTable. On extrait une trame de données df avec ho.to.df de ce tableau. Dans le cas où ce n'est pas NULL, nous le convertissons en matrice, et appliquons certaines opérations matricielles (par exemple, carré chaque élément) et renvoyons la sortie comme une nouvelle matrice.

Cette solution a été obtenue en utilisant la suggestion de Christo et l'approche de Stéphane.

3
Wolfi

Je ne sais pas si ce qui suit est ce que vous recherchez, mais voici. En supposant que vous pouvez entrer la matrice en tant que fichier texte/csv, la modification suivante de votre code ci-dessus fonctionnerait. C'est directement du tutoriel Shiny: http://rstudio.github.io/shiny/tutorial/#uploads

shiny::runApp(list(
    ui=pageWithSidebar(
        headerPanel('Simple matrixInput')
        ,
        sidebarPanel(
            fileInput('file1', 'Choose CSV File',
              accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv'))
            ,
            tags$hr(),
            checkboxInput('header', 'Header', TRUE),
            radioButtons('sep', 'Separator',
                 c(Comma=',',
                   Semicolon=';',
                   Tab='\t'),
                 'Comma'),
            radioButtons('quote', 'Quote',
                 c(None='',
                   'Double Quote'='"',
                   'Single Quote'="'"),
                 'Double Quote')
        )
        ,
        mainPanel(

            tableOutput(outputId = 'table.output')
        ))
    ,
    server=function(input, output){
        output$table.output <- renderTable({

        inFile <- input$file1

       if (is.null(inFile))
        return(NULL)

        tbl <- read.csv(inFile$datapath, header=input$header, sep=input$sep, quote=input$quote)
        return(tbl^2)
        })
    }
))

enter image description here

1
harkmug