Entrada reativa de renderDataTable
ATUALIZAÇÃO (18 de dezembro de 2015) A melhor abordagem atual para esse problema está aqui:Obter linha selecionada do DataTable no aplicativo brilhante
======================
Estou tentando reativamente exibir um conjunto de dados usando uma seleção de linha fornecida pelo usuário. Como um exemplo de brinquedo,
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))
})
Gostaria de usar o botão de opção para coletar o número da linha (digamos, linha 4 na imagem acima) do usuário usando alguma expressão reativa, digamosrowSelect()
e exiba dinamicamente a tabela após algumas operações no conjunto de dados, por exemplo,
mtcars[mtcars[,1] > mtcars[rowSelect(),1], input$show_vars, drop=FALSE]
que eliminaria determinadas linhas dinamicamente sempre que o usuário selecionasse uma linha.
ATUALIZAÇÃO (7-fev-14)
Incorporando as alterações sugeridas por @Julien e implementando o método sugerido por @Vincent,server.R torna-se:
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))
})
Como adivinhado por @agstudy, era importante manter o número de linhas na tabela de dados o mesmo de antes (sem subconjunto), portanto, a operação de classificação estranha acimaorder(mtcars[,1] - rnorm(nrow(mtcars), mtcars[rowSelect(),1]))
.
ATUALIZAÇÃO 2 (7-fev-14)
De qualquer forma, este exercício revela uma falha no meu exemplo. Minha intenção original era usar uma matriz de covariância / similaridade separada para obter a ordem de classificação da tabela de dados de exibição com base na linha selecionada pelo usuário. Como a matriz e a tabela seriam muito grandes, não fazia sentido incluí-las como lista de entrada suspensa ou qualquer outro método de entrada de botão de rádio no painel lateral. Tinha que vir da seleção do usuário depois de exibir toda a tabela de dados.
Para isso, basta substituir ovalue
no botão de opção com o ID da linha exclusivo. No server.R, usando orowSelect()
expressão (data
é a matriz de similaridade emeta
é a tabela de dados exibida,ID
é o identificador de linha exclusivo compartilhado pordata
emeta
):
addRadioButtons <- paste0('<input type="radio" name="row" value=', meta[order(data[rowSelect(),]),"ID"], '>')
cbind(Pick=addRadioButtons, meta[order(data[rowSelect(),]),input$show_vars])
Isso continuaria recorrendo à tabela de dados com base na linha selecionada pelo usuário e ao escolher o pedido com base na matriz de similaridade por meio de um ID de linha exclusivo. Espero que isso ajude alguém.
Mas se eu usar orowSelect
expressão reativa, a seleção de linhas com base em uma tabela de dados classificada não me daria a seleção de linhas correta para a matriz de similaridade (a ordem teria mudado para o conjunto de dados, mas não para a matriz - problema de recursão). Isso significa que eu precisaria coletar algo diferente de uma entrada de rádio do número da linha - algo mais como um ID de linha de identificação (que corresponderia à tabela - uma das colunas - e à matriz) usando um formulário ou um envio de clique - nas mesmas linhas:Selecionando todo o texto na entrada de texto HTML quando clicado
Obrigado pela ajuda. @Incent, seu aplicativo é muito legal. Espero chegar lá eventualmente. Eu aceitarei sua resposta.