I've got a dataTabe for which I'm trying to implement tableTools in order to export the records in csv format. However, when the filtered data is more than 1 page worth of records, as in the example provided here, the export button doesn't pick up the records on the 2nd page and onwards and it only exports the 1st page.
From my research, it appears that oSelectorOps:{ page: 'all' } option should do the trick. However I couldn't get it to work. If you run the code below and hit the export button, it will result in a csv file with only 100 rows (i.e. the first page) and not the entire table. Please advise if my syntax is incorrect or if there's a better alternative to attain this.
Please note that I don't want to use the downloadHandler because I would like to be able to export the data when filtered using the DataTable filter fields, at the bottom of the table.
Please click here and here to help with similar questions.
Here's my reproducible example:
#Load required packages
require(shiny)
#Create a dataframe
df <- data.frame(random=1:160)
server <- function(input,output,session){
#Display df using DataTable and apply desired options
output$display <- renderDataTable({df},
option=list(pageLength=100,
"dom" = 'T<"clear">lfrtip',
"tableTools" = list(
"sSwfPath" = "//cdn.datatables.net/tabletools/2.2.3/swf/copy_csv_xls_pdf.swf",
"aButtons" = list(list("sExtends" = "csv","oSelectorOpts"=list("page"="all"),"sButtonText" = "Export","aButtons" ="csv")))
)
)
}
ui <- shinyUI(fluidPage(
#Add a title
h1('Testing TableTools'),
#Add required JS libraries
tagList(
singleton(tags$head(tags$script(src='//cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js',type='text/javascript'))),
singleton(tags$head(tags$script(src='//cdn.datatables.net/tabletools/2.2.3/js/dataTables.tableTools.min.js',type='text/javascript'))),
singleton(tags$head(tags$link(href='//cdn.datatables.net/tabletools/2.2.3/css/dataTables.tableTools.css',rel='stylesheet',type='text/css')))
),
mainPanel(
#Display results
dataTableOutput('display')
)
))
shinyApp(ui = ui, server = server)
Try this out:
{
sExtends: "csv",
"oSelectorOpts": {
page: 'all',
filter:'applied'
},
"mColumns": "visible"
},
Related
I want to output a dataTable and preselect a row. This row can have a higher number than 10, in which case I want it to be shown in the dataTable. I have read you could use a dataTableProxy but it does not jump to the correct row. Is there an easy way to do this?
Here a minimal example:
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("dtout")
)
server <- function(input, output, session) {
output$dtout<- DT::renderDT(iris)
dtproxy<-DT::dataTableProxy(session = session,outputId = "dtout")
DT::selectRows(dtproxy,14)
}
shinyApp(ui, server)
This is the result:
This is what I want to be shown directly:
Is there an easy way to do so?
You can achieve that by using the Select extension. But you have to know in advance the number of the page to be displayed (maybe there's a way to get it automatically, I don't know).
library(DT)
callback <- "
table.row(':eq(13)', {page: 'all'}).select(); // select row 13+1
table.page(1).draw('page'); // jump to page 1+1
"
datatable(
iris,
extensions = "Select", selection = "none",
callback = JS(callback)
)
I have made an shiny app where I am giving a fileInput where user can input an excel sheet like this: 'enter image description here'. I have designed an app which looks like this: 'enter image description here'. My code is this:
library(shiny)
library(readxl)
library(tidyverse)
ui <- fluidPage(
fileInput("config","Load Configuration File",accept =c('.xls',',xlsx')),
actionButton("show_fields","Show Fields"),
actionButton("estimate","Estimate"),
uiOutput("ui"),
textOutput("prod")
)
server <- function(input,output) {
x <- reactive({read_excel(input$config$datapath)})
conf <- reactive({x() %>% column_to_rownames(., var = "Rows")})
design <- eventReactive(input$show_fields, {
fluidPage(
numericInput("size","Size",value = 0),
lapply(1:nrow(conf()),function(i) {
selectInput(row.names(conf())[i],label = row.names(conf())[i],choices = colnames(conf()))
})
)
})
output$ui <- renderUI({design()})
mul <- eventReactive(input$estimate, {
sapply(1:nrow(conf()), function(j) {
conf()[row.names(conf())[j],eval(parse(text = paste0("input$",row.names(conf())[j],sep = "")))]
})
})
output$prod <- renderText({paste("Product is: ",prod(mul(),na.rm = TRUE)*input$size)})
}
shinyApp(ui=ui,server = server)
when loading the xls sheet, 'Show Fields' button will show all the Rows as Drop-downs with columns as choices. So at last whatever I choose upon clicking 'Estimate' button Product will be shown of all corresponding values from excel sheet and the inputed size.
So now what I want:
1: All the boxes (numericInput & selectInputs) shall come in two or three columns. The page shall look filled.
2: The actual excel sheet I do have is not exactly I have shown above. It is actually like one you can see in the following image: 'enter image description here'.
Here A-E,U-Z,K-O are drop-downs choices, for corresponding rows(like A-Z for Ram, Shyam etc. , U-Z for Predeep, Sudeep and K-O for Aneeta). I want each such dropdowns and whatever user selects I need to provide the product of all corresponding values from excel sheet along with given Size.
I am trying this out for many days now, and now I am frustated. Somebody please do it.
I am trying to create a UI on which I can upload a file and also there is a text input where I can write the product name which I want to search in the uploaded file. I am doing that using the Levenshtein Distance function (adist() function). Now, once i get the results for which the edit distance is 0, I want to display those rows in the Table on the Main Panel. Whatever input is given in the Text input on the UI is searched against the items column in the file uploaded. A sample image of the CSV file which is uploaded is this-
Sample image of the CSV file which is input by the user
Once I run the code and find the edit distance for all the words, I store them in a vector and then use this to print the rows from the file which have edit distance equal to 0. The problem is that when I click on submit, the result is not displayed on the UI but it is displayed on the R-studio console. How do I fix this?
Please help me with the code.
library(shiny)
ui = shinyUI(fluidPage(
titlePanel("LEVENSHTEIN DISTANCE function trial"),
sidebarLayout(
sidebarPanel(
numericInput("rows","Enter the number of rows",value=NULL),
textInput("product", "input product name"),
br(),
br(),
fileInput("file", "Input the file"),
submitButton("Find!")),
mainPanel(
tableOutput("result")
)
)
))
server = shinyServer(function(input,output) {
output$result <- renderPrint({ if (is.null(input$file)) return( );
trial = read.csv(input$file$datapath)
ls = vector('list', length = input$rows)
for(i in 1:input$rows) {
edit = adist("earbuds", trial$items[i])
new_edit = as.numeric(edit)
ls[i] = edit
if(ls[i]==0) print(trial[i, ])
}
})
})
shinyApp(ui=ui,server=server)
Thank You!
It is very hard to provide working code without sample input date. But, here is my attempt at giving you what I think should work.
server = shinyServer(function(input,output) {
output$result <- renderTable({
if (!is.null(input$file)) {
trial = read.csv(input$file)
trial <- trial[adist('earbuds', trial$items) == 0), ]
}
})
})
If you provide input data and expected output table, I can edit the answer to be more precise.
I am trying to create a responsive data table for my shiny application using DT package. I want to hide certain columns in advance. For example:
library("shiny")
library("DT")
shinyApp(
ui = fluidPage(DT::dataTableOutput('tbl')),
server = function(input, output) {
output$tbl = DT::renderDataTable(
iris,extensions="Responsive"
)
}
)
This output gives me 5 columns. It only hides columns when I narrow the page. But, I want to hide last 3 columns in advance and I just want to see first two columns every time. Is there a way to do that?
Update:
Example output
You can hide columns in your table using DT options or extensions.
If you want them to be hidden in advance but have a button to make them visible again, the ColVis extension should work well for you: link
If you just want thme stay hidden, add the following option (can't remember where I've seen its documentation right now..)
options=list(columnDefs = list(list(visible=FALSE, targets=columns2hide)))
I have another way which I like for its readability. It does not solve the problem of column numbering though.
library("shiny")
library("DT")
library(magrittr)
columns2hide <- match('Sepal.Width', colnames(iris))
shinyApp(
ui = fluidPage(DT::dataTableOutput('tbl')),
server = function(input, output) {
output$tbl = DT::renderDataTable(
{
dataTableProxy(outputId = 'tbl') %>%
hideCols(hide = columns2hide)
iris
},
extensions="Responsive"
)
}
)
dataTableProxy creates a proxy object that you can operate on with a couple of functions (see ?dataTableProxy).
It can be handy for hiding/showing/selecting/add/... rows and columns of the table when clicking on a button, for example.
Because it has deferUntilFlush = TRUE by default it waits with its handling of the table until its next generation. In this case this simply happens on the following line.
I want to modify this application:
https://demo.shinyapps.io/029-row-selection/
so that only one row can be selected at a time, and so that I can acquire the item in the first column of the selected row to plot data with. Does anyone know how to do this?
UPDATE: you can now access the selected rows using input$tableId_rows_selected in server.R. See here for more details.
To select a unique row, you can change the callback function of your example to this:
callback = "function(table) {
table.on('click.dt', 'tr', function() {
table.$('tr.selected').removeClass('selected');
$(this).toggleClass('selected');
Shiny.onInputChange('rows',
table.rows('.selected').data()[0][0]);
});
}"
When you click on a row,it basically removes any selected rows (they have the .selected class) and selects the row you clicked on.
I also changed the code in the Shiny.onInputChange function so that it returns the number in the first column.
The R method which renders a DataTable has a parameter which defines the selection mode. For example:
output$table1 <-
DT::renderDataTable(dataSet,
selection = 'single')
Possible values are ('multiple' is the default):
none
single
multiple
For further reference you can see: http://rstudio.github.io/DT/shiny.html
EDIT 04/14/2016
In the setup I use working with single selection mode has issues.
Here is what version I use:
> DT:::DataTablesVersion
[1] "1.10.7"
> packageVersion("DT")
[1] ‘0.1’
The problem I faced is that visually you have a single row selection but when you do:
observeEvent(input$table1_rows_selected, {
str(input$table1_rows_selected)
})
You will get a list with all rows which were selected but were not explicitly deselected. In other words selecting a new row does not automatically deselect the previous row in the internal Datatables logic. This might be also due to the DT wrapper, not sure.
This is why currently as a workaround we use JS for this:
$(document).on('click', '#table1 table tr', function() {
var selectedRowIds = $('#table1 .dataTables_scrollBody table.dataTable').DataTable().rows('.selected')[0];
var selectedId = "";
if (selectedRowIds.length === 1) {
selectedId = $(this).children('td:eq(0)').text();
} else {
$('#table1 tbody tr').removeClass('selected');
}
Shiny.onInputChange("table1_selected_id", selectedId);
});
Once you have this in place you will be able to do:
observeEvent(input$table1_selected_id, {
str(input$table1_selected_id)
})
This now at least sends correct data to your server.R code. Unfortunately you will still have an issue with the table because internally it keeps track on which rows were selected and if you switch pages it will restore a wrong selection. But at least this is purely a visual defect and your code will have the chance to function properly. So this solution actually needs more work.
You can use this:
output$data_table <- renderDataTable(data(),options = list(pageLength = 9))
Then to get the selected row:
selected <- input$data_table_rows_selected
Then to get cells from that row, you can use (assuming that time is the name of the col you are trying to get in this case):
time_x = data()[selected, "time"]
Selected is the index for the selected rows, so you need to use that index along with the col name.
The below code display a dataframe in DT table format. Users will be able to select single row. The selected row is retrieved and displayed. you can write your plot function in the plot block in the server.
I hope this helps !!
# Server.R
shinyServer(function(input, output,session) {
output$sampletable <- DT::renderDataTable({
sampletable
}, server = TRUE,selection = 'single')
output$selectedrow <- DT::renderDataTable({
selectedrowindex <<- input$sampletable_rows_selected[length(input$sampletable_rows_selected)]
selectedrowindex <<- as.numeric(selectedrowindex)
selectedrow <- (sampletable[selectedrowindex,])
selectedrow
})
output$plots <- renderPlot({
variable <- sampletable[selectedrowindex,1]
#write your plot function
})
})
#ui.R
shinyUI(navbarPage( "Single Row Selection",
tabPanel("Row selection example",
sidebarLayout(sidebarPanel("Parameters"),
mainPanel(
DT::dataTableOutput("selectedrow"),
DT::dataTableOutput("sampletable")
))
)
))
# global.R
library(DT)
library(shiny)
selectedrowindex = 0