Thanks for the time.
I am trying to get a shiny app to work correctly, and for some reason I am having difficulty on a highlighting issue when rendering a DT data table.
For example, this works:
output$DT = DT::renderDataTable({DT = datatable(DT,options = list(searching = FALSE,paging = FALSE,lengthChange = FALSE,ordering = FALSE,rownames= FALSE)) %>%
formatStyle('TEST',backgroundColor = styleEqual(c(1,2,3,4,5), c('chartreuse', 'chartreuse4','yellow','indianred','indianred4'))) )})
However, when attempting to add this additional line, the highlighting is not appearing, yet the code runs:
%>%
formatStyle('TEST2',backgroundColor = styleEqual(c(TRUE,FALSE),c('green','red'))
I have also tried styleInterval, and am getting the same results.
Thanks.
Reproducible Code:
ui <- fluidPage(
dataTableOutput('DF')
)
server <- function(input, output, session) {
DF = as.data.frame(matrix(NA,nrow=2,ncol = 2))
DF$V1 = c(TRUE,FALSE)
DF$V2 = c(1,2)
output$DF = renderDataTable(DF)
output$DF = DT::renderDataTable({DF = datatable(DF,options = list(searching = FALSE,paging = FALSE,lengthChange = FALSE,ordering = FALSE,rownames= FALSE)) %>%
formatStyle('V2',backgroundColor = styleEqual(c(1,2,3,4,5), c('chartreuse', 'blue','yellow','indianred','indianred4'))) %>%
formatStyle('V1',backgroundColor = styleEqual(c(TRUE,FALSE),c('green','red')))})
}
shinyApp(ui = ui, server = server) # RUN THE APPLICATION
> styleEqual(c(TRUE,FALSE),c('green','red'))
[1] "value == 'TRUE' ? 'green' : value == 'FALSE' ? 'red' : ''"
attr(,"class")
[1] "JS_EVAL"
value is not 'TRUE' or 'FALSE', it is true or false.
You can do:
...... %>%
formatStyle('V1',
backgroundColor = JS("value == true ? 'green' : value == false ? 'red' : ''"))
Related
This is UMAP function and by entering the colors names you can color the clusters but it is not working. It says that it sees only one color and 20 are needed. This is Seurat package.
This is the function that I used originally without shiny and it works
DimPlot(data, reduction = "umap", cols = c(colors[30], colors[1], colors[2], colors[28], colors[3],
colors[4], colors[5], "mistyrose", "lightpink4", colors[21], "grey", colors[7], colors[9], colors[11], colors[24], colors[26], "magenta" ,"gold", "mistyrose2"), split.by = "orig.ident")
This code below if from the shiny app I am making
server <- function(input, output) {
col = renderText({ input$label.color })
cols <- reactive({input$cols})
output$value <- renderText({ input$cols})
output$tsneplot<-renderPlot({
input$ts
if (input$spl == "NULL") {
isolate(DimPlot(data, seed = input$seed.use,reduction = "tsne",pt.size=input$pt.size, label = T, repel = T, label.size = input$label.size, cells = NULL, cols = NULL, label.color = "red"))
} else {
isolate(DimPlot(data, reduction = "tsne",pt.size= input$pt.size, split.by = input$spl ,cells = NULL, cols = c(cols()), label = T, label.size = input$label.size, label.color = col(), repel = T ))
}
})
}
I have seen the output value of text cols it shows exactly in the upper portion of the code below but for some reason while it is in the app and running the dimplot function it thinks it is only one string. Without the concept of shiny it works the code is tested but in the shiny platform it is not.
enter image description here
To examine what value cols() actually returns in your app, you can include a console-like output in your test version:
ui <- fluidPage(
## ...
verbatimTextOutput('log')
## ...
)
server <- function(input, output, session) {
## ...
output$log <- renderPrint(cols())
## ...
}
I can't figure out what is wrong with this code. My shiny give the error when I click on the action button PlotContemp, so I think the problem is somewhere in the mvar function. When I run this code with the same data but outside the Shiny, it works great!So is there a problem with the reactive expressions? I will appreciate some help!
observeEvent(store$df, {
req(store$df)
updateSelectInput(session, "NetVariables", choices = colnames(store$df),
selected = "Anxiety")
})
Vars <- reactive({
Vars <- c(input$NetVariables)
return(Vars)
})
type <- reactive({
type <- rep("g",length(Vars()))
for (v in length(Vars())) {
if (class(store$df[Vars()][[v]]) == "character") {
type[v] <- "c"
}
}
})
levels <- reactive({
levels <- rep(1, length(Vars()))
for (v in length(Vars())) {
if (class(store$df[Vars()][[v]]) == "character") {
levels[v] <- 2
}
}
})
observeEvent(input$PlotContemp, {
req(store$df)
mvar1 <- mvar(store$df[,Vars()], type = type(),
level = levels(), lags=1, dayvar = store$df$day, beepvar = store$df$beep, lambdaSel = "CV", lambafolds = 10, overparameterize = FALSE, k=2, ruleReg = "AND")
qgraph(mvar1$wadj[,,1],
edge.color = mvar1$edgecolor,
layout = "spring",
labels = vars)
})
I'm working on cancer data from TCGA.
Im new to shiny and creating web applications (learning it!!)
I'm working on a shiny tool to plot the volcanoplot using highcharter package.
sometimes I'm successfully able to plot the volcanoplot in the UI. but sometimes it fails to plot it and throws an error saying,
"An error has occurred!
could not find function "highchartOutput"
and one warning message is given for the error;
Listening on http://127.0.0.1:5335
Warning: Error in highchartOutput: could not find function "highchartOutput"
83: dots_list
82: div
81: tabPanel
I think there is some problem with the tabset panel.
is this error has anything to do with indentation? (wherever I adjust the brackets it works magically. not sure how it works for sometimes.)
I am attaching the UI and server files with this post.
code is attached for one type of comparison
UI file below:
library(shiny)
# Define UI for application
shinyUI(fluidPage(
# Application title
titlePanel("miR-Gyn-Explorer"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
## select the count matrix
selectInput("file", label = h3("Count Matrix"),
choices = list("Stage I - Normal" = list("TCGA-BRCA" = "Data/TCGA-BRCASI_NT.rda", "TCGA-UCEC" = "Data/TCGA-UCECSI_NT.rda"))),
## select the phenodata of samples
selectInput("phenofile", label = h3("Sample Phenodata"),
choices = list("Stage I - Normal" = list("TCGA-BRCA" = "Data/TCGA-BRCA_phenoSI_NT.rda", "TCGA-UCEC" = "Data/TCGA-UCEC_phenoSI_NT.rda"))),
submitButton("Update View")
),
# Show a plot of the generated distribution
mainPanel(
tabsetPanel(
tabPanel("DEmiRNA", DT::dataTableOutput("DEmiRNA"),
"Volcano-Plot", highchartOutput("volcanoPlot", height = "500px"))
#tabPanel("miRNA-Targets", DT::dataTableOutput('miRTarget'),
#plotOutput("GO"))
)
)
)
)
)
server file:
library(shiny)
library(R.utils)
##function to find the DEmiRNA by edgeR method
library(limma)
library(edgeR)
library(DT)
library(dplyr)
library(multiMiR)
library(miRBaseConverter)
library(ggplot2)
#library(ggrepel)
library(tidyverse)
library(highcharter)
library(org.Hs.eg.db)
library(clusterProfiler)
library(purrr)
gdcDEmiRNA <- function(counts, groups, comparison, filter=TRUE) {
## method = edgeR
dge = DGEList(counts = counts, samples = groups)
group <- factor(groups$group)
design <- model.matrix(~0+group)
colnames(design) <- levels(group)
contrast.matrix <- makeContrasts(contrasts=comparison,
levels=design)
keep = filterByExpr(dge,design)
dge <- dge[keep,,keep.lib.sizes = TRUE]
dge <- calcNormFactors(dge)
dge <- estimateDisp(dge, design)
fit <- glmFit(dge, design)
lrt <- glmLRT(fit, contrast=contrast.matrix)
DEGAll <- lrt$table
DEGAll$FDR <- p.adjust(DEGAll$PValue, method = 'fdr')
o <- order(DEGAll$FDR)
DEGAll <- DEGAll[o,]
return (DEGAll)
}
# Define server logic required to perform the DEmiRNA analysis
server <- function(input, output) {
d <- reactive({
#DEmiRNA calculation
file <- load(input$file)
phenofile <- load(input$phenofile)
if(file == "SI_NT"){
if(phenofile == "phenoSI_NT"){
DEmiRNA <- gdcDEmiRNA(counts = SI_NT, groups = phenoSI_NT,
comparison = 'StageI-Normal')
}
}
})
output$DEmiRNA <- DT::renderDataTable({
mir <- d()
#mir <- mir[mir$FDR < input$FDR,]
})
output$volcanoPlot <- renderHighchart({
x <- d()
x$mirna <- rownames(x)
x$sig <- ifelse(x$PValue < 0.05 & abs(x$logFC) > 0.57, "DEmiRNA", "Not Regulated")
hc <- highchart() %>%
hc_add_series(x, "scatter", hcaes(logFC, -log10(PValue), group = sig, value = mirna),
color = c('rgba(67, 67, 72, 0.6)', 'rgba(124, 181, 236, 0.6)'),
enableMouseTracking = c(TRUE, TRUE),
showInLegend = TRUE, marker = list(radius = 4)) %>%
hc_tooltip(pointFormat = "{point.value}", headerFormat = "") %>%
hc_xAxis(title = list(text = "Log fold change"), gridLineWidth = 1,
tickLength = 0, startOnTick = "true", endOnTick = "true", min = -6, max = 6) %>%
hc_yAxis(title = list(text = "-Log10(p-value)")) %>%
hc_chart(zoomType = "xy", width=700) %>%
hc_exporting(enabled = TRUE, filename = "volcano")
hc
})
}
any comment and help from you guys is appreciated
Thank you in advance!
-Ankita
The application
On startup, a 3 x 3 table is generated with values from 1 to 9 in a random order. What the app user can see is a blank 3 x 3 rhandsontable that he/she will use to try to guess where the generated values are. When the user clicks on the "Submit" button, the cells that contain the correct values turn green and all other cells remain as they are.
My issue
The cells where the user guessed right do not turn green when the user clicks the button. In other words, the conditional formatting does not work even though I got it to work before (that was in the first version of the app when I did not make use of shiny modules).
What I have done
The full project is in the following Github repository that potential users may want to clone instead of copying and pasting the code below: https://github.com/gueyenono/number_game
My project folder has 4 files. The first two files are the usual ui.R and server.R, which essentially call shiny modules (i.e. hot_module_ui() and hot_module()) . The modules are contained within the global.R file. The last file, update_hot.R, contains a function used in the modules.
ui.R
This file loads the required packages, provides a title for the app and calls hot_module_ui(). The module just displays a blank 3 x 3 rhandsontable and an actionButton().
library(shiny)
library(rhandsontable)
source("R/update_hot.R")
ui <- fluidPage(
titlePanel("The number game"),
mainPanel(
hot_module_ui("table1")
)
)
server.R
This file calls the hot_module(), which contains the code for the conditional formatting.
server <- function(input, output, session) {
callModule(module = hot_module, id = "table1")
}
update_hot.R
This is the function which is called when the "Submit" button is called. The function has two arguments:
hot: the handsontable in the app
x: the values generated on startup
This is what the function does (full code for the file is at the end of this section):
Get the user inputs
user_input <- hot_to_r(hot)
Compare user inputs (user_input) to the true values (x) and store the row and column indices of the cells where the user guessed right
i <- which(user_input == x, arr.ind = TRUE)
row_correct <- i[, 1] - 1
col_correct <- i[, 2] - 1
Update the current handsontable object with the row and column indices and use the renderer argument of the hot_cols() function to make background of corresponding cells green. Note that I use the hot_table() function to update the existing rhandsontable object.
hot %>%
hot_table(contextMenu = FALSE, row_correct = row_correct, col_correct = col_correct) %>%
hot_cols(renderer = "function(instance, td, row, col, prop, value, cellProperties){
Handsontable.renderers.TextRenderer.apply(this, arguments);
if(instance.params){
// Correct cell values
row_correct = instance.params.row_correct
row_correct = row_correct instanceof Array ? row_correct : [row_correct]
col_correct = instance.params.col_correct
col_correct = col_correct instanceof Array ? col_correct : [col_correct]
for(i = 0; i < col_correct.length; i++){
if (col_correct[i] == col && row_correct[i] == row) {
td.style.background = 'green';
}
}
return td;
}")
Here is the full code for update_hot.R
update_hot <- function(hot, x){
# Get user inputs (when the submit button is clicked)
user_input <- hot_to_r(hot)
# Get indices of correct user inputs
i <- which(user_input == x, arr.ind = TRUE)
row_correct <- i[, 1] - 1
col_correct <- i[, 2] - 1
# Update the hot object with row_index and col_index for user in the renderer
hot %>%
hot_table(contextMenu = FALSE, row_correct = row_correct, col_correct = col_correct) %>%
hot_cols(renderer = "function(instance, td, row, col, prop, value, cellProperties){
Handsontable.renderers.TextRenderer.apply(this, arguments);
if(instance.params){
// Correct cell values
row_correct = instance.params.row_correct
row_correct = row_correct instanceof Array ? row_correct : [row_correct]
col_correct = instance.params.col_correct
col_correct = col_correct instanceof Array ? col_correct : [col_correct]
for(i = 0; i < col_correct.length; i++){
if (col_correct[i] == col && row_correct[i] == row) {
td.style.background = 'green';
}
}
return td;
}")
}
global.R
This is the file, which contains the shiny modules. The UI module (hot_module_ui()) has:
- an rHandsontableOutput
- an actionButton
- I added a tableOutput in order to see where the generated values are (useful for testing the code)
The server module (hot_module()) calls the update_hot() function and attempts to update the handsontable in the app whenever the user clicks on the "Submit" button. I attempted to achieve this by using an observeEvent and a reactive value react$hot_display. On startup, react$hot_display contains a 3 x 3 data frame of NAs. When the button is clicked, it is updated with the new version of the handsontable (containing user inputs and conditional formatting). Here is the full code for global.R:
hot_module_ui <- function(id){
ns <- NS(id)
tagList(
rHandsontableOutput(outputId = ns("grid")),
br(),
actionButton(inputId = ns("submit"), label = "Submit"),
br(),
tableOutput(outputId = ns("df"))
)
}
hot_module <- function(input, output, session){
values <- as.data.frame(matrix(sample(9), nrow = 3))
react <- reactiveValues()
observe({
na_df <- values
na_df[] <- as.integer(NA)
react$hot_display <- rhandsontable(na_df, rowHeaders = NULL, colHeaders = NULL)
})
observeEvent(input$submit, {
react$hot_display <- update_hot(hot = input$grid, x = values)
})
output$grid <- renderRHandsontable({
react$hot_display
})
output$df <- renderTable({
values
})
}
As mentioned at the beginning, the conditional formatting does not work when the "Submit" button is clicked and I am not sure why. Once again, you can access the full code on the following Github repository:
https://github.com/gueyenono/number_game
I finally found the solution to my issue. One of the biggest lessons I learned was that the hot_to_r() function does not work in custom functions. It must be used in the server function of a shiny app. This means that passing an rhandsontable object to a custom function and retrieving the data from within the function may not be a good idea (which was my story).
I am not sure it will be of interest to anyone, but here is my code, which works as intended:
ui.R
library(rhandsontable)
library(shiny)
source("R/update_hot.R")
shinyUI(fluidPage(
# Application title
titlePanel("The Number Game"),
module_ui(id = "tab")
))
server.R
library(shiny)
shinyServer(function(input, output, session) {
callModule(module = module_server, id = "tab")
})
global.R
module_ui <- function(id){
ns <- NS(id)
tagList(
rHandsontableOutput(outputId = ns("hot")),
actionButton(inputId = ns("submit"), label = "OK"),
actionButton(inputId = ns("reset"), label = "Reset")
)
}
module_server <- function(input, output, session){
clicked <- reactiveValues(submit = FALSE, reset = FALSE)
initial_hot <- rhandsontable(as.data.frame(matrix(NA_integer_, nrow = 3, ncol = 3)))
correct_values <- as.data.frame(matrix(1:9, nrow = 3, byrow = TRUE))
observeEvent(input$submit, {
clicked$submit <- TRUE
clicked$reset <- FALSE
})
updated_hot <- eventReactive(input$submit, {
input_values <- hot_to_r(input$hot)
update_hot(input_values = input_values, correct_values = correct_values)
})
observeEvent(input$reset, {
clicked$reset <- TRUE
clicked$submit <- FALSE
})
reset_hot <- eventReactive(input$reset, {
initial_hot
})
output$hot <- renderRHandsontable({
if(!clicked$submit & !clicked$reset){
out <- initial_hot
} else if(clicked$submit & !clicked$reset){
out <- updated_hot()
} else if(clicked$reset & !clicked$submit){
out <- reset_hot()
}
out
})
}
R/update_hot.R
update_hot <- function(input_values, correct_values){
equal_ids <- which(input_values == correct_values, arr.ind = TRUE)
unequal_ids <- which(input_values != correct_values, arr.ind = TRUE)
rhandsontable(input_values) %>%
hot_table(row_correct = as.vector(equal_ids[, 1]) - 1,
col_correct = as.vector(equal_ids[, 2]) - 1,
row_incorrect = as.vector(unequal_ids[, 1]) - 1,
col_incorrect = as.vector(unequal_ids[, 2]) - 1) %>%
hot_cols(renderer = "function(instance, td, row, col, prop, value, cellProperties){
Handsontable.renderers.TextRenderer.apply(this, arguments);
if(instance.params){
// Correct cell values
row_correct = instance.params.row_correct
row_correct = row_correct instanceof Array ? row_correct : [row_correct]
col_correct = instance.params.col_correct
col_correct = col_correct instanceof Array ? col_correct : [col_correct]
// Incorrect cell values
row_incorrect = instance.params.row_incorrect
row_incorrect = row_incorrect instanceof Array ? row_incorrect : [row_incorrect]
col_incorrect = instance.params.col_incorrect
col_incorrect = col_incorrect instanceof Array ? col_incorrect : [col_incorrect]
for(i = 0; i < col_correct.length; i++){
if (col_correct[i] == col && row_correct[i] == row) {
td.style.background = 'green';
}
}
for(i = 0; i < col_incorrect.length; i++){
if (col_incorrect[i] == col && row_incorrect[i] == row) {
td.style.background = 'red';
}
}
}
return td;
}")
}
When I'm trying to run this code as a Shiny app in R, I'm facing this error:
Error in renderDataTable({ : unused argument (rownames = FALSE)
output$table <- renderDataTable({
if(is.null(fdata()))
{return ()}
if(input$flevel=="Weekly")
{
if(input$flevel2=="Store")
{
data<-fdata()
data <- data[data$SKU == input$xcol,]
data <- data[data$Store == input$ycol,]
data
}
else if(input$flevel2=="Region")
{
data<-fdata()
data <- data[data$SKU == input$xcol,]
data <- data[data$Region == input$ycol,]
# data <- aggregate(Sales~Date+SKU+Region_Name,data = data,FUN = sum,na.rm=TRUE)
data
}
}
else if(input$flevel=="Monthly")
{
if(input$flevel2=="Store")
{
dmsales<-MonthManp()
data<-dmsales[[4]]
data <- data[data$SKU == input$xcol,]
data <- data[data$Store == input$ycol,]
data
}
else if(input$flevel2=="Region")
{
dmsales<-MonthManp()
data<-dmsales[[4]]
data <- data[data$SKU == input$xcol,]
data <- data[data$Region == input$ycol,]
data
# data <- aggregate(Sales~Date+product_id+loc_id+Channel_Name,data = data,FUN = sum,na.rm=TRUE)
}
} }, options = list(searching = FALSE),rownames=FALSE)
All my brackets are properly closed and the rownames is inside the datatable not the options tab. Can anyone pls help me in this. I'm a newbie in Shiny.
The params for
renderDataTable are:
renderDataTable(expr, options = NULL, searchDelay = 500,
callback = "function(oTable) {}", escape = TRUE, env = parent.frame(),
quoted = FALSE, outputArgs = list())
You could use the following format:
output$table <- DT::renderDataTable({
DT::datatable(df,options = list(searching=FALSE),rownames= FALSE)
})
Hope this helps!