来自renderDataTable的无效输入

时间:2014-02-06 22:45:06

标签: r shiny reactive-programming

更新(2015年12月18日) 这个问题的当前最佳应用是:Get Selected Row From DataTable in Shiny App

======================

我正在尝试使用用户提供的行选择来反复重新显示数据集。作为一个玩具的例子,

ui.R

library(shiny)

shinyUI(pageWithSidebar(
  headerPanel('Examples of DataTables'),
  sidebarPanel(
    checkboxGroupInput('show_vars', 'Columns to show:', names(mtcars),
                       selected = names(mtcars))
  ),
  mainPanel(
               dataTableOutput("mytable")
    )
  )
)

server.R

library(shiny)

shinyServer(function(input, output) {

  # sorted columns are colored now because CSS are attached to them
  output$mytable = renderDataTable({
    addRadioButtons <- paste0('<input type="radio" name="row', 1:nrow(mtcars), '" value="', 1:nrow(mtcars), '">',"")
    #Display table with radio buttons
    cbind(Pick=addRadioButtons, mtcars[, input$show_vars, drop=FALSE])
  }, options = list(bSortClasses = TRUE, aLengthMenu = c(5, 25, 50), iDisplayLength = 25))

})

Hypothetical Reactive Input from DataTable

我想使用单选按钮从用户那里使用一些反应式表达式(比如rowSelect())收集行号(比如上图中的第4行),然后动态地重新显示表格。对数据集的操作,例如,

 mtcars[mtcars[,1] > mtcars[rowSelect(),1], input$show_vars, drop=FALSE]

每次用户选择一行时都会动态删除某些行。

更新(7-feb-14)

结合@Julien建议的更改并实施@Vincent建议的方法, server.R 变为:

library(shiny)

shinyServer(function(input, output) {

  #reactive row-selection 
  rowSelect <- reactive({
  if(is.null(input[["row"]])) 1 #initialize
  else as.numeric(input[["row"]])})

  # User-selected sorting of dataset
  output$mytable = renderDataTable({
    addRadioButtons <- paste0('<input type="radio" name="row" value="', 1:nrow(mtcars), '">')
    cbind(Pick=addRadioButtons, mtcars[order(mtcars[,1] - rnorm(nrow(mtcars), mtcars[rowSelect(),1])), input$show_vars, drop=FALSE])
  }, options = list(bSortClasses = TRUE, aLengthMenu = c(5, 10, 20), iDisplayLength = 10))
})

正如@agstudy所猜测的那样,重要的是保持数据表中的行数与以前相同(不是子集),因此奇怪的排序操作高于order(mtcars[,1] - rnorm(nrow(mtcars), mtcars[rowSelect(),1]))

更新2(7-feb-14)

无论如何,这个练习确实揭示了我的例子中的一个缺陷。我最初的意图是使用一个单独的协方差/相似度矩阵来获得基于用户选择的行的显示数据的排序顺序。由于矩阵和表格非常大,因此将它们作为下拉输入列表或侧面板中的任何其他单选按钮输入方法包含在内是没有意义的。它必须在显示整个数据表后来自用户选择。

要实现此目的,只需使用唯一的行ID替换radiobutton中的value即可。在server.R中,使用rowSelect()表达式(data是相似性矩阵,meta是显示的数据表,IDdata共享的唯一行标识符}和meta):

addRadioButtons <- paste0('<input type="radio" name="row" value=', meta[order(data[rowSelect(),]),"ID"], '>')

cbind(Pick=addRadioButtons, meta[order(data[rowSelect(),]),input$show_vars])

这将继续基于用户选择的行求助数据表,同时通过唯一的行ID基于相似性矩阵选择顺序。希望这有助于某人。

但是,如果我使用rowSelect反应式表达式,那么基于排序数据表的行选择将无法为相似性矩阵提供正确的行选择(订单将更改为数据集,但不是矩阵 - 递归问题)。这意味着我需要收集除行号的无线电输入之外的其他内容 - 更像是一个标识行ID(可以匹配表 - 列中的一个 - 和矩阵),使用表格或点击提交 - 按照以下方式提交:Selecting all text in HTML text input when clicked

感谢您的帮助。 @Vincent,你的应用非常酷。希望最终到达那里。我会接受你的回答。

1 个答案:

答案 0 :(得分:1)

不是答案,而是一个长篇评论:我认为你可以做到这一点,但它会有点混乱。一旦某些人选择了一个单选按钮并显示了数据的子集,您将如何返回显示所有数据?这仅适用于第一列吗?当数据行数较少时,您是否要重新创建所有单选按钮? renderDataTable(在某些时候)可以选择包含'&gt;之类的内容每列下方框中的20'。与此同时,您最好尝试使用textInput对数据进行子集化。例如,请参阅数据&gt;在此app中查看。如果那不是你想要的,那么让我(我们)知道你想要达到的目标。