В Shiny обновите DataTable новыми значениями, введенными пользователем.

Я пишу блестящее приложение, в котором есть таблица (с использованием DT::renderDataTable), из которой пользователи могут выбирать строку. Но я хочу, чтобы пользователь также мог добавлять новую строку (строки), если то, что они хотят, еще нет в таблице. Я использую элементы управления вводом, чтобы пользователь вводил новые данные, и у меня есть кнопка действия, которая при нажатии должна создать новую строку данных в таблице из входных значений. Но нажатие кнопки не обновляет таблицу.

Минимальный пример:

library(shiny)
library(DT)
mydata = data.frame(id=letters[1:5], val=sample(10,5,T))

ui = fluidPage(dataTableOutput("table"),
               textInput('NewID', 'Enter new ID'),
               numericInput('NewVal', 'Enter new val', 1),
               actionButton("goButton", "Update Table"))

server = function(input,output){
  output$table = renderDataTable(mydata)
  update = eventReactive(input$goButton, {
    newrow = data.frame(id = input$NewID, val = input$NewVal)
    mydata = rbind(mydata, newrow)
  })
}

shinyApp(ui,server)

Ясно, что это неправильный подход. Я пробовал различные комбинации обертывания renderDataTable и кода для обновления mydata внутри renderUI, observe и reactive, но я не могу найти правильный способ сделать это.

Это мое первое блестящее приложение, так что, возможно, есть основная концепция, которую я не совсем понимаю. Какой правильный путь?


person dww    schedule 25.11.2016    source источник
comment
@HubertL Вы получаете эту ошибку при вставке и запуске кода? У меня все нормально.   -  person dww    schedule 25.11.2016
comment
Мне нужно указать valueпараметр для numericInput()   -  person HubertL    schedule 25.11.2016
comment
Спасибо @HubertL - я добавил это к примеру. Должна быть версия, по какой-то причине она не выдает ошибку, когда значение отсутствует.   -  person dww    schedule 25.11.2016


Ответы (2)


Вы можете отобразить результат eventReactive, где вы вернете обновленный набор данных. Не забудьте также использовать <<- для изменения глобального набора данных:

server = function(input,output){
  output$table <- renderDataTable( df())
  df <- eventReactive(input$goButton, {
    if(input$NewID!="" && !is.null(input$NewVal) && input$goButton>0){
      newrow = data.table(id = input$NewID,
                        val = input$NewVal)
      mydata <<- rbind(mydata, newrow)
      }
    mydata
  }, ignoreNULL = FALSE)
}
person HubertL    schedule 25.11.2016
comment
Превосходно! Это почти готово. Единственная небольшая проблема заключается в том, что он добавляет новую строку с пустым идентификатором до нажатия кнопки. Вы знаете, как это подавить? - person dww; 26.11.2016
comment
Я добавил чек input$goButton>0, означающий, что кнопка была нажата - person HubertL; 26.11.2016

Вы должны использовать replaceData() функцию из пакета DT. Пример:

...
  dataTableOutput("OPreview"),
  actionButton("BRefresh","Refresh"),
...

in server part(assuming ds is a dataset to show):

output$OPreview<-renderDataTable({ ds })

onclick("BRefresh",{
  proxy=dataTableProxy("OPreview")
  replaceData(proxy,ds)
})

person Sergiy Iurenko    schedule 16.02.2019