R Shiny: Formatting reactive data.frame from sql query - r

I am trying to figure out how i can change type of the column after getting the data from reactive sql query...
for example when i fetch the data from database, some of the columns are characters, and i wish them to be factors. And some of the columns are numeric (which is correct) but i need them to be displayed as factors in datatable (for use in the datatable, as the column named is Tolerance, and tolerance cannot be filtered by range, it should be one single number).
Simple code:
library(ROracle)
library(shiny)
library(DT)
server <- shinyServer(
function(input, output, session) {
con <- dbConnect(dbDriver("Oracle"),"xx/K",username="user",password="pwd")
tableList <- dbListTables(con,schema="K")
updateSelectizeInput(session, "tabnames", server = TRUE, choices = tableList)
sqlOutput <- reactive({
sqlInput <- paste("select rownum * from K.",input$tabnames)
dbGetQuery(con$cc, sqlInput, stringsAsFactors = T)#it hasnt worked neither
})
output$table <- DT::renderDataTable(sqlOutput(), server=TRUE, rownames=TRUE, filter="top", options=list(pageLength=10))
session$onSessionEnded(function() { dbDisconnect(con) })
})
ui_panel <-
tabPanel("Test",
sidebarLayout(
sidebarPanel(
),
mainPanel(
selectizeInput("tabnames",label = "server side", choices = NULL),
tableOutput("out"),
tableOutput("table")
)
)
)
ui <- shinyUI(navbarPage("Test",ui_panel))
runApp(list(ui=ui,server=server))
When i have tried simply:
output$table <- DT::renderDataTable({
sqlOutput()$HOEHE_TOLP <- as.factor(sqlOutput()$HOEHE_TOLP)
datatable(sqlOutput(), server=TRUE, rownames=TRUE, filter="top", options=list(pageLength=10))})
It didnt work, and gave me an error:
Error in sqlOutput()$HOEHE_TOLP <- as.factor(sqlOutput()$HOEHE_TOLP) :
ungültige (NULL) linke Seite in Zuweisung
*invalid (NULL) left side of assignment
Any ideas how i can convert some columns to factors for reactive data frame?
Cheers

EDIT:
Simply replace this expression:
output$table <- DT::renderDataTable(sqlOutput(), server=TRUE,
rownames=TRUE, filter="top", options=list(pageLength=10))
With:
output$table <- DT::renderDataTable({
intermed <- sqlOutput()
intermed$HOEHE_TOLP <- as.factor(intermed$HOEHE_TOLP)
datatable(intermed) %>% formatStyle("RUND2_MITT", color = 'red',
backgroundColor = 'lightyellow', fontWeight = 'bold')
}, server=TRUE, rownames=TRUE, filter="top", options=list(pageLength=10))
Here is a self contained example:
library(DT)
library(shiny)
ui <- fluidPage(
actionButton("inst", "Instigate Reactive"),
dataTableOutput("test")
)
server <- function(input, output){
data <- eventReactive(input$inst, {
iris
})
output$test <- renderDataTable({
set <- data()
set$Sepal.Length <- as.factor(set$Sepal.Length)
datatable(set) %>% formatStyle("Petal.Length", color = 'red',
backgroundColor = 'lightyellow',
fontWeight = 'bold')
})
}
shinyApp(ui, server)

Related

rclipButton in DataTable R Shiny

I'm hoping to insert an rclipboard::rclipButton() into a DataTable in RShiny and am having trouble figuring out how to do it. Have tried the following (based on: Using renderDataTable within renderUi in Shiny):
library(shiny); library(tidyverse); library(rclipboard)
ui <- fluidPage(
mainPanel(
rclipboardSetup(),
uiOutput('myTable')
)
)
server <- function(input, output) {
output$myTable <- renderUI({
output$myTable <- renderUI({
iris <- iris %>% filter(row_number()==1:2)
iris$button <- rclipButton(
inputId = "clipbtn",
label = "Copy",
clipText = "test",
icon = icon("clipboard")
)
output$aa <- renderDataTable(iris)
dataTableOutput("aa")
})
})
}
shinyApp(ui, server)
But looks like this:
"[object Object]"
Have also tried paste0()'ing the rclipButton() into the DataTable but that just renders as a long string of HTML.
Any suggestions much appreciated!
Well, rclipButton() call will generate shiny.tag objects, and you need to change it to string so DT can parse it. Then the key is to use escape = F in datatable.
I also rewrite the way to generate the DT table.
library(shiny); library(tidyverse); library(rclipboard)
ui <- fluidPage(
mainPanel(
rclipboardSetup(),
DT::dataTableOutput("aa")
)
)
server <- function(input, output) {
output$aa <- DT::renderDataTable({
iris2 <- iris %>% filter(row_number()==1:2)
iris2$button <- rclipButton(
inputId = "clipbtn",
label = "Copy",
clipText = "test",
icon = icon("clipboard")
) %>% as.character()
DT::datatable(iris2, escape = F)
})
}
shinyApp(ui, server)

Counting the number of unique vector in columns of input data in shiny r

I'm trying to figure out the number of unique vector in selected input using my data.
However, all of the results of the variables' length(unique(x)) is 1.
Could you help me how to fix this problem?
Here's my code.
library(shiny)
ui <- fluidPage(
fluidRow(
box(width = 6, height=200, title ="File select",
fileInput("file","select file", buttonLabel = "file", accept = c(".csv")),
DTOutput('dt')),
selectInput("sel","select",colnames(file)),
verbatimTextOutput("results")
)
)
server <- function(input, output, session) {
data <- reactive({
data.table::fread(input$file$datapath)
})
observeEvent(input$file, {
mytable <- read.csv(input$file$datapath) %>% as_tibble()
req(mytable)
updateSelectInput(session, "sel", label = "select", choices = colnames(mytable))
})
output$results <- renderPrint({
length(unique(data()[,input$sel]))
})
}
shinyApp(ui, server)
################### solution ######################
server <- function(input, output, session) {
appdata <- reactive({
read.csv(input$file$datapath)
})
observeEvent(input$file, {
mydf <- read.csv(input$file$datapath)
updateSelectInput(session, "sel", label = "select", choices = colnames(mydf))
})
output$results <- renderPrint({
cat(input$sel, '\n')
length(unique(appdata()[[input$sel]]))
})
}
It does work for me!!
The data object returned by fread is a data.table:
library(data.table)
data <- function(){ as.data.table(mtcars)}
length(unique(data()[,1]))
#> [1] 1
nrow(unique(data()[,1]))
#> [1] 25
Created on 2020-08-30 by the reprex package (v0.3.0)
The reason for this is that with a data.frame / data.table, data[,1] returns another data.frame / data.table (a list of list with 1 column).
length gives the number of columns, nrow is what you're looking for.

How to replaceData in DT rendered in R shiny using the datatable function

I have an R shiny app with a DT datatable that is rendered using the datatable function in order to set various options. I would like to use dataTableProxy and replaceData to update the data in the table, but all the examples I can find assume the DT is rendered directly from the data object, not using the datatable function. The reprex below shows what I would like to do, but replaceData doesn't work in this pattern. How do I do this? Thanks.
# based on
# https://community.rstudio.com/t/reorder-data-table-with-seleceted-rows-first/4254
library(shiny)
library(DT)
ui = fluidPage(
actionButton("button1", "Randomize"),
fluidRow(
column(6,
h4("Works"),
DT::dataTableOutput('table1', width="90%")),
column(6,
h4("Doesn't Work"),
DT::dataTableOutput('table2', width="90%"))
)
)
server = function(input, output, session) {
my <- reactiveValues(data = iris)
output$table1 <- DT::renderDataTable(isolate(my$data))
output$table2 <- DT::renderDataTable({
DT::datatable(isolate(my$data),
options = list(lengthChange=FALSE, ordering=FALSE, searching=FALSE,
columnDefs=list(list(className='dt-center', targets="_all")),
stateSave=TRUE, info=FALSE),
class = "nowrap cell-border hover stripe",
rownames = FALSE,
editable = FALSE
) %>%
DT::formatStyle('Sepal.Width', `text-align`="center")
})
observeEvent(input$button1, {
# calculate new row order
row_order <- sample(1:nrow(my$data))
my$data <- my$data[row_order, ]
proxy1 <- DT::dataTableProxy('table1')
DT::replaceData(proxy1, my$data)
proxy2 <- DT::dataTableProxy('table2')
DT::replaceData(proxy2, my$data)
})
}
shinyApp(ui, server)
Update: Very strangely, removing rownames = FALSE made it all possible. I'm not exactly sure why, but probably rownames might be essential for replacing Data.
# based on
# https://community.rstudio.com/t/reorder-data-table-with-seleceted-rows-first/4254
library(shiny)
library(DT)
ui = fluidPage(
actionButton("button1", "Randomize"),
fluidRow(
column(6,
h4("Works"),
DT::dataTableOutput('table1', width="90%")),
column(6,
h4("Doesn't Work"),
DT::dataTableOutput('table2', width="90%"))
)
)
server = function(input, output, session) {
my <- reactiveValues(data = iris)
output$table1 <- DT::renderDataTable(isolate(my$data))
output$table2 <- DT::renderDataTable({
DT::datatable(isolate(my$data),
options = list(lengthChange=FALSE, ordering=FALSE, searching=FALSE,
columnDefs=list(list(className='dt-center', targets="_all")),
stateSave=TRUE, info=FALSE),
class = "nowrap cell-border hover stripe",
# rownames = FALSE,
editable = FALSE
) %>%
DT::formatStyle('Sepal.Width', `text-align`="center")
})
observeEvent(input$button1, {
# calculate new row order
row_order <- sample(1:nrow(my$data))
my$data <- my$data[row_order, ]
proxy1 <- DT::dataTableProxy('table1')
DT::replaceData(proxy1, my$data)
proxy2 <- DT::dataTableProxy('table2')
DT::replaceData(proxy2, my$data)
})
}
shinyApp(ui, server)

R Shiny - Dynamic Filtering from a CSV File - Rows Go Missing

When using filtering and the verbatimTextOutput function in R Shiny, rows go seemingly go missing when I select more than one of the input choices in my checkboxGroupInput.
Below is my code. Any advice?
Thanks in advance.
infantmort <- read.csv("infantmort.csv", header = TRUE)
ui <- fluidPage(
checkboxGroupInput("regioninputID",
"Select Region(s)",
choices = unique(infantmort$whoregion)
),
mainPanel(
verbatimTextOutput("regionoutputID"), width = "auto", height = "auto"
)
)
server <- function(input, output) {
dataset <- reactive({
as.data.frame(infantmort %>% select(whoregion, year, deathsinthousands) %>%
filter(whoregion == input$regioninputID) )
})
output$regionoutputID <- renderPrint({ dataset()
})
}
shinyApp(ui = ui, server = server)
You need to change your filter from == to %in%
The following should do the trick
server <- function(input, output) {
dataset <- reactive({
as.data.frame(infantmort %>% select(whoregion, year, deathsinthousands) %>%
filter(whoregion %in% input$regioninputID) )
})

Using a selected row to subset another table in r shiny

I am new to using DT in R shiny.Basically what i am trying to do here is to use the select value from the first table to filter the second table.
my Ui.r is
library(shiny)
library(shinydashboard)
ui <- dashboardPage(skin="green",
dashboardHeader(title="Inventory Management"),
dashboardSidebar(disable = TRUE),
dashboardBody(fluidRow(column(4,box(status="success",
uiOutput("Firstselection"),
br(),
uiOutput("Secondselection"))
),
column(4,infoBoxOutput("salesbox")),
column(4,infoBoxOutput("Runoutbox")),
column(4,infoBoxOutput("Excessbox"))),
actionButton("actionbtn","Run"),
fluidRow(tabBox(tabPanel(
DT::dataTableOutput(outputId="table"),title = "Stock Available for the category chosen",width = 12),
tabPanel(DT::dataTableOutput(outputId="asso"),title = "Associated products",width = 12)))
))
and my server is
server <-function(input, output, session) {
observeEvent(input$actionbtn, {source('global.r',local = TRUE)
#choose sub category based on category
output$Firstselection<-renderUI({selectInput("ray",
"Category:",
c("All",unique(as.character(bestpred$lib_ray))))})
output$Secondselection<-renderUI({selectInput("sray",
"Sub Category:",
c("All",unique(as.character(bestpred[bestpred$lib_ray==input$ray,"lib_sray"]))))})
# Filter data based on selections
output$table <- DT::renderDataTable({
data <- bestpred
if (input$ray != "All"){
data <- data[data$lib_ray == input$ray,]
}
if (input$sray != "All"){
data <- data[data$lib_sray == input$sray,]
}
data
},filter="top"
)
output$salesbox<-renderInfoBox({infoBox("Total Sales",sum(data()$Total_Sales),icon = icon("line-chart"))})
output$Runoutbox<-renderInfoBox({infoBox("Total Runout",sum(data()$status=="Runout"),icon = icon("battery-quarter"))})
output$Excessbox<-renderInfoBox({infoBox("Total excess",sum(data()$status=="Excess"),icon = icon("exclamation-triangle"))})
output$asso <- DT::renderDataTable({
asso <- test1
s=data[input$tablatable_rows_selected,1]
asso <- asso[asso$num_art == s,]
asso
},filter="top")
})}
So when i select a row in the output table i wanna use that as an filter for my asso table
this code dosent poup any error but the output table asso is always empty
Find a generalized solution in the following:
Adapted from here: https://yihui.shinyapps.io/DT-rows/
library(shiny)
library(DT)
server <- shinyServer(function(input, output, session) {
output$x1 = DT::renderDataTable(cars, server = FALSE)
output$x2 = DT::renderDataTable({
sel <- input$x1_rows_selected
if(length(cars)){
cars[sel, ]
}
}, server = FALSE)
})
ui <- fluidPage(
fluidRow(
column(6, DT::dataTableOutput('x1')),
column(6, DT::dataTableOutput('x2'))
)
)
shinyApp(ui, server)

Resources