How to Implement DataTables Option in Shiny R syntax? - r

I am trying to add an option for DataTable in Shiny using some of the expanded options that are found in DataTables.
I want to implement the opetion SearchBuilder.columns so that the search box can only search in the "id" column
https://datatables.net/reference/option/searchBuilder.columns
How does one implement this option into R Shiny? What is the syntax?
The code below did not work.
output$table_pred <- DT::renderDataTable(df, options = list(pageLength =5), searchBuilder.columns = df$id)
Here is the full code:
library(shinythemes)
library(shiny)
library(DT)
setwd("c:/Desktop/datasets/")
df <- read.csv("prediction_data.csv")
df2 <- read.csv("test_data.csv")
ui <- fluidPage(
fluidRow(
column(12,
dataTableOutput('table_pred')
)
),
fluidRow(
column(12,
dataTableOutput('table_test')
)
)
)
server <- function(input, output, session) {
#rendering the datatable for rediction data
output$table_pred <- DT::renderDataTable(df, options = list(pageLength =5), searchBuilder.columns = df$id)
output$table_test <- DT::renderDataTable(df2,options = list(pageLength =10))
}
shinyApp(ui, server)

Awesome extension!
It is not available in the 'DT' package. Here is how you can use it.
Firstly, download the JavaScript file and the CSS file.
Then, here is the R code:
library(DT)
library(htmltools)
dat <- data.frame(
x = c(0, 1, 2, 3, 4),
id = c("sub0", "sub0", "sub1", "sub1", "sub2")
)
dtable <- datatable(
dat,
options = list(
dom = "Qlfrtip",
searchBuilder = list(
columns = list(2) # 2 is the index of the 'id' column
)
)
)
path_to_searchBuilder <- # path to the folder containing the two searchBuilder files
normalizePath("~/Work/R/DT/searchBuilder/")
dep <- htmlDependency(
name = "searchBuilder",
version = "1.0.0",
src = path_to_searchBuilder,
script = "dataTables.searchBuilder.min.js",
stylesheet = "searchBuilder.dataTables.min.css",
all_files = FALSE
)
dtable$dependencies <- c(dtable$dependencies, list(dep))
dtable

Related

Using SelectInput to reference the correct dataframe for use

Hi I'm relatively new to Shiny and am not sure how to do this. I am making a dashboard that should first pull the relevant dataframe based on user selectInput, after which further selectInput functions will further filter down the sheet for the relevant price. However, I can't seem to link the InputId from the selectInput to the relevant dataframe name. (Below is code)
UI.R
ui <- navbarPage(
"Dashboard",
tabPanel(
"Cost1",
fluidPage(
selectInput("type",
label = "Select Type",
choices = NULL),
textOutput("message")
)
)
)
Server.R
#load libraries, data
library(tidyr)
library(readxl)
library(dplyr)
library(purrr)
a <- read_excel('source.xlsx', sheet = 'a')
b <- read_excel('source.xlsx', sheet = 'b')
c <- read_excel('source.xlsx', sheet = 'c')
mylist <- list(a = a, b = b, c = c)
server <- function(input, output, session) {
updateSelectInput(session,
"type",
choices = names(mylist))
material = reactive(input$type)
price <- material[1,"price"]
output$message <- renderText({
paste(price)
})
}
Thank you!
There is a few things that need to correct in your original code - here is my code for 3 files global.R, server.R, and ui.R with detail explanation comments. (my habit of separating them so it easier to manage.
global.R
#load libraries, data
library(shiny)
library(tidyr)
library(readxl)
library(dplyr)
library(purrr)
# This is just a generation of sample data to be used in this answer.
set.seed(1)
generate_random_df <- function(name) {
tibble(
product = paste0(name, "-", round(runif(n = 10, min = 1, max = 100))),
price = runif(10))
}
a <- generate_random_df("a")
b <- generate_random_df("b")
c <- generate_random_df("c")
mylist <- list(a = a, b = b, c = c)
server.R
set.seed(1)
generate_random_df <- function(name) {
tibble(
product = paste0(name, "-", round(runif(n = 10, min = 1, max = 100))),
price = runif(10))
}
a <- generate_random_df("a")
b <- generate_random_df("b")
c <- generate_random_df("c")
mylist <- list(a = a, b = b, c = c)
server <- function(input, output, session) {
updateSelectInput(session,
"type",
choices = names(mylist))
# to extract the data you need to reference to mylist as the Input only take
# the name of your list not the dataset within it
price <- reactive({
# Here the material command also inside the reactive not as you do initially
material <- mylist[[input$type]]
paste0(material[1,"price"])
})
# You don't need renderText for this just assign the value to message
output$message <- price
# I also output the table for easier to see
output$price_table <- renderTable(mylist[[input$type]])
}
ui.R
ui <- navbarPage(
"Dashboard",
tabPanel(
"Cost1",
fluidPage(
selectInput("type",
label = "Select Type",
choices = NULL),
textOutput("message"),
tableOutput("price_table")
)
)
)
Here is the screenshot of the app

Shiny -How to save to excel every change in renderTable?

I use Timevis package.
first of all I read an excel file with missions.
In my code the user can see all the missions on a time line, and he can edit/add/remove any missions.
after the user make a change I can see the update table below.
I want to save to my excel file every update that the user make.
this is my code:
library(shiny)
library(timevis)
library(readxl)
my_df <- read_excel("x.xlsx")
data <- data.frame(
id = my_df$id,
start = my_df$start,
end = my_df$end,
content = my_df$content
)
ui <- fluidPage(
timevisOutput("appts"),
tableOutput("table")
)
server <- function(input, output) {
output$appts <- renderTimevis(
timevis(
data,
options = list(editable = TRUE, multiselect = TRUE, align = "center")
)
)
output$table <- renderTable(
input$appts_data
)
}
shinyApp(ui, server)
You can use actionButton/ observe to call saveworkbook (package openxlsx) to save your changes. Technically you are not saving these changes, but replacing the file with an identical file containing the changes.
library(shiny)
library(openxlsx)
library(timevis)
library(readxl)
my_df <- read_excel("x.xlsx")
data <- data.frame(
id = my_df$id,
start = my_df$start,
end = my_df$end,
content = my_df$content
)
mypath = paste0(getwd(), "/x.xlsx") # Path to x.xlsx
ui <- fluidPage(
timevisOutput("appts"),
tableOutput("table"),
actionButton("save", "Save")
)
server <- function(input, output) {
output$appts <- renderTimevis(
timevis(
data,
options = list(editable = TRUE, multiselect = TRUE, align = "center")
))
observeEvent(input$save,
{
my_df<- createWorkbook()
addWorksheet(
my_df,
sheetName = "data"
)
writeData(
wb = my_df,
sheet = "data",
x = input$appts_data,
startRow = 1,
startCol = 1
)
saveWorkbook(my_df, file = mypath,
overwrite = TRUE)
})
output$table <- renderTable(
input$appts_data
)
}
shinyApp(ui, server)

Save filtered DT::datatable into a new dataframe R shiny

Let's say that I have a shiny app displaying a data table like the following:
library(shiny)
library(tidyverse)
library(datasets)
library(DT)
data<- as.data.frame(USArrests)
#data<- cbind(state = rownames(data), data)
ui <- fluidPage(
dataTableOutput("preview")
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$preview<- renderDataTable(
datatable(data, options = list(searching = T, pageLength = 10, lengthMenu = c(5,10,15, 20), scrollY = "600px", scrollX = T ))
)
}
# Run the application
shinyApp(ui = ui, server = server)
Let's say I then type in "Iowa" into the search box. I would like to save that filtered datatable into a seperate dataframe within the app. I would like it to be dynamic as well so if I typed "Kentucky", it would save Kentucky's filtered data into the dataframe instead. Is there a way to do this?
NOTE: this is a DT datatable
Maybe this type of solution. It is possible to add further conditions like checking the first letter in upper case, but the main idea is to check each column and search for the pattern entered inside the datatable searchbox. This may or may not result in more than one dataset to print (depending if the string is partially matched in multiple columns (this is also solvable with rbind function.
code:
library(shiny)
library(tidyverse)
library(datasets)
library(DT)
data <- as.data.frame(USArrests)
data <- cbind(state = rownames(data), data)
ui <- fluidPage(
dataTableOutput("preview"),
tableOutput('filtered_df')
)
# Define server logic required to draw a histogram
server <- function(input, output) {
df <- reactiveValues()
output$preview<- renderDataTable(
datatable(data, options = list(searching = T, pageLength = 10, lengthMenu = c(5,10,15, 20), scrollY = "600px", scrollX = T ))
)
observeEvent(input$preview_search, {
searched_string <- map(data, ~str_subset(.x, input$preview_search)) %>% discard(~length(.x) == 0)
df$filtered <- syms(names(data)) %>%
map(~ filter(data, !!.x %in% searched_string)) %>%
discard(~ nrow(.x) == 0)
})
output$filtered_df <- renderTable({df$filtered})
}
# Run the application
shinyApp(ui = ui, server = server)

Render datatable with sparklines in Shiny

I want to include sparklines in a shiny DT. It works fine in the RStudio viewer but in Shiny the sparklines are not rendered. Here is a minimal example.
# dependencies
require(sparkline)
require(DT)
require(shiny)
# create data with sparklines
spark_data <- data.frame(
id = c('spark1', 'spark2'),
spark = c(
spk_chr(values = 1:3, elementId = 'spark1'),
spk_chr(values = 3:1, elementId = 'spark2')
)
)
# render in RStudio viewer (this works)
tbl <- datatable(spark_data, escape = FALSE)
spk_add_deps(tbl)
# render in Shiny (no sparklines rendered in DT)
ui <- fluidPage(
sparklineOutput("test_spark"),
dataTableOutput("tbl")
)
server <- function(input, output) {
# sparkline outside DT (works fine) - also ensures sparkline dependencies are attached
output$test_spark <- renderSparkline(sparkline(1:3))
# sparkline inside DT (does not render)
output$tbl <- renderDataTable(
expr = spark_data,
escape = FALSE
)
}
shinyApp(ui = ui, server = server)
I have modified your code to generate sparklines. I refered to this link to generate the sparklines.
require(sparkline)
require(DT)
require(shiny)
# create data
spark_data1<- data.frame(id = c('spark1', 'spark2'),
spark = c("1,2,3", "3,2,1"))
ui <- fluidPage(
sparklineOutput("test_spark"),
DT::dataTableOutput("tbl")
)
server <- function(input, output) {
line_string <- "type: 'line', lineColor: 'black', fillColor: '#ccc', highlightLineColor: 'orange', highlightSpotColor: 'orange'"
cd <- list(list(targets = 1, render = JS("function(data, type, full){ return '<span class=sparkSamples>' + data + '</span>' }")))
cb = JS(paste0("function (oSettings, json) {\n $('.sparkSamples:not(:has(canvas))').sparkline('html', { ",
line_string, " });\n}"), collapse = "")
output$tbl <- DT::renderDataTable({
dt <- DT::datatable(as.data.frame(spark_data1), rownames = FALSE, options = list(columnDefs = cd,fnDrawCallback = cb))
})
}
shinyApp(ui = ui, server = server)
Hope it helps!
Old-ish question, I know, but based on info in the question Add label to sparkline plot in datatable I think the solution is what you tried originally plus just a few lines. Here I trimmed out the parts demo-ing it works in the viewer and added just what is needed to make the sparklines work.
# dependencies
require(sparkline)
require(DT)
require(shiny)
# create data with sparklines
spark_data <- data.frame(
id = c('spark1', 'spark2'),
spark = c(
spk_chr(values = 1:3, elementId = 'spark1'),
spk_chr(values = 3:1, elementId = 'spark2')
)
)
### adding this <------------
cb <- htmlwidgets::JS('function(){debugger;HTMLWidgets.staticRender();}')
ui <- fluidPage(
### and this <------------
htmlwidgets::getDependency('sparkline'),
dataTableOutput("tbl")
)
server <- function(input, output) {
output$tbl <- renderDataTable(
expr = spark_data,
escape = FALSE,
### and this <------------
options = list(
drawCallback = cb
)
)
}
shinyApp(ui = ui, server = server)

Natural sorting in Shiny DT (datatables) doesn't work

Dear Shiny and DT masters!
I'm trying to use natural sorting plugin in my shiny app, but it doesn't seem to work. I think it was working with previous version of Shiny or/and before DT package. Can anybody help me? See my example below (I'm trying to sort the last column):
server.R
library(shiny)
require(DT)
shinyServer(function(input, output) {
output$example <- DT::renderDataTable({
table = cbind(LETTERS[1:5],matrix(1:20,nrow=5),c(1,2,3,10,"a"))
table = rbind(c("filtered",round(rnorm(5),3)),table)
DT::datatable(table,
rownames = FALSE,
extensions = list(FixedColumns = list(leftColumns = 1)),
options = list(
columnDefs = list(list(type = "natural", targets = "_all"))))
})
})
ui.R
library(shiny)
require(DT)
shinyUI(
fluidPage(
tags$head(
tags$script(src = "http://cdn.datatables.net/1.10.6/js/jquery.dataTables.min.js", type = "text/javascript"),
tags$script(src = "http://cdn.datatables.net/plug-ins/1.10.7/sorting/natural.js", type = "text/javascript")
),
DT::dataTableOutput('example')
)
)
In the current development version of DT (>= 0.1.16), you can enable this plug-in using datatable(..., plugins = 'natural'), e.g.
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
DT::dataTableOutput('example')
),
server = function(input, output) {
output$example <- DT::renderDataTable({
table = cbind(LETTERS[1:5],matrix(1:20,nrow=5),c(1,2,3,10,"a"))
table = rbind(c("filtered",round(rnorm(5),3)),table)
table
}, server = FALSE, plugins = 'natural', options = list(
columnDefs = list(list(type = "natural", targets = "_all"))
))
}
)
See the documentation for more information.

Resources