Ввод данных через shinyTable в R блестящем приложении

Я хочу создать блестящее приложение, которое получает данные матрицы как входные данные и возвращает таблицу на основе некоторых операций над ней в качестве вывода. По поиску я нахожу, что пакет ShinyTable может быть полезен. Я попробовал под блестящими кодами, но в результате приложение выглядит серым и без результата.

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 
    )
  }
))

Любая идея?

Ответы

Ответ 1

Пакет shinyTable был значительно улучшен в пакете rhandsontable.

Вот минимальная функция, которая берет фрейм данных и запускает блестящее приложение, позволяющее редактировать его и сохранять в файле 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())
}

Например, возьмите следующий фрейм данных:

> ( 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

Запустите приложение и получайте удовольствие (особенно с календарями ^^):

введите описание изображения здесь

Отредактируйте handsontable:

введите описание изображения здесь

Нажмите кнопку "Сохранить". Он сохраняет таблицу в файле table.rds. Затем прочитайте его в 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

Ответ 2

Если вы ищете решение, в котором пользователи могут вводить данные своей матрицы, как в excel, вы, вероятно, можете взглянуть на пакет "shinySky" и, более конкретно, на его компонент "Handsontable Input/Output". Соответствующий веб-адрес: https://github.com/AnalytixWare/ShinySky.

Другим подобным решением будет пакет shinyTable. Дополнительную информацию можно найти на https://github.com/trestletech/shinyTable

Ответ 3

Я не уверен, что следующее, что вы ищете, но здесь. Предполагая, что вы можете ввести матрицу в виде файла text/csv, тогда будет работать следующая модификация вашего кода выше. Это прямо из учебника 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

Ответ 4

Вы можете использовать hotable("matrixTable") из 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
)

В пользовательском интерфейсе ui визуализируются ввод "matrixTable" и "resultTable". server инициализирует эти таблицы, так что matrixTable можно редактировать. Это означает, что вы можете копировать и вставлять данные из Excel или изменять значения вручную. Функция observe активируется, всякий раз, когда замечено изменение на входе matrixTable. Мы извлекаем из этой таблицы фрейм данных df с ho.to.df. В случае, если не NULL, мы преобразуем его в матрицу и применим некоторые матричные операции (например, квадрат каждого элемента) и вернем результат как новую матрицу.

Это решение было получено с использованием предложения Christo и подхода Стефана.