Add Sparklines to Multiple Columns of R Data Table using Sparkline package - r

I am trying to add sparklines to multiple columns of a Data Table in R. I am able to get a single Sparkline column to render correctly, but when I try to render a sparkline in a second column based on different underlying data than the first, the same sparkline is displayed in the second column. I imagine there is some snippet of code needed in the fnDrawCalback option, but I have not been able to find much out there addressing my issue.
Here is a reproducible example for both a single sparkline (works) and a two sparklines (just repeats the first sparkline in both columns)
# create data with single sparkline column
library(sparkline)
library(DT)
spark_data <- data.frame(
id = c('spark1', 'spark2'),
spark = c(
spk_chr(values = 1:3, elementId = 'spark1'),
spk_chr(values = 3:1, elementId = 'spark2')
)
)
tbl <- datatable(spark_data, escape = F,
rownames = F
, options = list(fnDrawCallback = htmlwidgets::JS('function(){
HTMLWidgets.staticRender();
}'))
)
spk_add_deps(tbl)
# create data with two sparkline columns
library(sparkline)
library(DT)
spark_data <- data.frame(
id = c('spark1', 'spark2'),
spark = c(
spk_chr(values = 1:3, elementId = 'spark1'),
spk_chr(values = 3:1, elementId = 'spark2')
),
second_spark = c(spk_chr(values = 3:1, elementId = 'spark1'),
spk_chr(values = 1:3, elementId = 'spark2'))
)
tbl <- datatable(spark_data, escape = F,
rownames = F
, options = list(fnDrawCallback = htmlwidgets::JS('function(){
HTMLWidgets.staticRender();
}'))
)
spk_add_deps(tbl)

Related

How to style reactable cell background with custom grouping select

I have some data I'm trying to present using reactable. I am styling the background of cells based on the value. There are a number of groups in the data which are useful, but the groups themselves do not have an aggregated value that is useful.
The issue I'm facing is that when the data is grouped with the custom grouping select, the table will retain the style of the first few rows of data so the background is coloured. I would like it to be blank for the grouped row.
In the example below, when grouping by group you'll notice that A and C have the background coloured, inheriting the style from rows 1 and 3 in the data. I could imagine a hacky way of organizing the data so only non-stylized rows come first, but that is not really appropriate as the data would be too disorganized at initial presentation.
Is there a way to strip the style when grouped, but retain it for the rows with values?
library(reactable)
library(htmltools)
set.seed(1)
data <- data.frame(
group = rep(c("A", "B", "C"), each = 5),
value = rnorm(15)
)
htmltools::browsable(
tagList(
div(tags$label("Group by", `for` = "tab")),
tags$select(
id = "tab",
onchange = "Reactable.setGroupBy('tab', this.value ? [this.value] : [])",
tags$option("None", value = ""),
tags$option("Group", value = "group"),
),
reactable(
data,
columns = list(
value = colDef(style = function(value){
if (value < 0) list(background = "#ffa500")
})
),
defaultPageSize = 15,
elementId = "tab"
)
)
)
I found a way using JavaScript. I've changed the variable value to num in the example below so it's more clear how to apply the function.
The grouping is done via JavaScript in the browser, so there isn't a way to control group styling in R as far as I'm aware.
library(reactable)
library(htmltools)
set.seed(1)
data <- data.frame(
group = rep(c("A","B","C"), each = 5),
num = rnorm(15)
)
htmltools::browsable(
tagList(
div(tags$label("Group by", `for` = "tab")),
tags$select(
id = "tab",
onchange = "Reactable.setGroupBy('tab', this.value ? [this.value] : [])",
tags$option("None", value = ""),
tags$option("Group", value = "group"),
),
reactable(
data,
columns = list(
num = colDef(style = JS("function(rowInfo) {
var value = rowInfo.row['num']
if (value < 0) {
var background = '#ffa500'
}
return {background: background}
}"))
),
defaultPageSize = 15,
elementId = "tab"
)
)
)

Shiny datatable, filter columns by background color (as we have in excel)

How to filter out columns in shiny DT datatable based on cell color. Just like we have in excel.
[Need to filter the column with yellow color in background.]
Below is the code for cells with color:
input_data <- data.frame(Record_Status = c("Modified","NO","NO","Modified","NO","NO","Modified","NO","NO"),
Field_Changed = c("Brand,ratio","Gender","Name","ratio,Name,Gender","cost","Brand,cost","ratio,cost","cost","Name"),
Brand = c(3,6,9,12,15,18,21,24,27),
ratio = c (1,2,3,4,5,6,7,8,9),
cost = c(3,6,9,12,15,18,21,24,27),
Name = c("A","B","C","A","B","C","A","B","C"),
Gender = c("A","B","C","A","B","C","A","B","C"),
stringsAsFactors = FALSE)
# Build hidden logical columns for conditional formatting
dataCol_df <- ncol(input_data)
dataColRng <- 3:dataCol_df
argColRng <- (dataCol_df + 1):(dataCol_df * 2 -2)
df <- sapply(1:ncol(input_data),function(i) ifelse(input_data[[1]]=="Modified" &
str_detect(input_data[[2]], names(input_data)[i]),
"1","0"))
df <- df[,-c(1,2)]
input_data <- data.frame(input_data, df)
# Create Shiny Output
shinyApp(
ui =
navbarPage("Testing",dataTableOutput('dt')),
server = function(input, output, session) {
output$dt = DT::renderDataTable(
datatable(input_data,
# Hide logical columns
options=list(columnDefs = list(list(visible=FALSE,
targets=argColRng)))) %>%
# Format data columns based on the values of hidden logical columns
formatStyle(columns = dataColRng,
valueColumns = argColRng,
backgroundColor = styleEqual(c('1', '0'),
c("yellow", "white")))
)}
)
I think you have more than I issue here. For me the shiny app is not running and I believe this might be due to a mixup what should be in the ui and what in the server function.
About your original question. You could use the library DT and color the cells you like. This is independent of your shiny app, however, I believe you can use this also in the app, once you have the app running without the coloring.
library(DT)
datatable(input_data) %>% formatStyle(
'Brand', 'X1',
backgroundColor = styleEqual(c(0, 1), c('gray', 'yellow'))
)

Change sparkline coloring in shiny DT table

Below is the code to develop sparkline in R. Wanted to check if we can change the color . I mean the negative values to be black and positive values to be red
library(shiny)
library(DT)
library(data.table)
library(sparkline)
## Create demo data sets
my_mtcars <- data.table(mtcars, keep.rownames = TRUE)
names(my_mtcars)[1] <- 'car_id'
set.seed(0)
data_for_sparklines <- data.table(car_id = rep(my_mtcars$car_id, 5),
category = 1:5,
value = c(runif(80),-runif(80)))
sparkline_html <- data_for_sparklines[, .(sparkbar = spk_chr(value, type = 'bar',barColor = "black")), by = 'car_id']
my_mtcars <- merge(my_mtcars, sparkline_html, by = 'car_id')
spk_add_deps(datatable(my_mtcars, escape = FALSE))

How can I make the color scale in mapdeck static

I am developing a shiny app which steps through time by each hour and shows the precipitation on a mapdeck map. I read in the weather data for the entire day and using reactivity filtering the data for the hour and plotting them as scatterplot using mapdeck_update to update the data. The color scale changes whenever the map updates based on the range of data in that hour. What I want is a static color scale based on the data range for the day. Is it possible?
I have tried using manual colors but for some reason they are not working
library(mapdeck)
ui <- fluidPage(
fluidRow(sliderInput(inputId = "hr",label = "Hour",min = 1,max = 3,value = 1)),
fluidRow(mapdeckOutput(outputId = "wx"))
)
sr <- function(input, output, session) {
mydata <- read.table(header=TRUE, sep=",",text="
ROW,COL,Center Latitude,Center Longitude,vil_int_36,hr
28,439,23.669885449218786,-97.2498101160108,20,1
41,433,24.37845221074034,-97.59803936272704,21,1
59,441,25.35333762373948,-97.11966878019186,22,1
61,441,25.461905262766468,-97.11878391116397,23,1
62,443,25.515163854569053,-96.99946877404128,24,1
29,439,23.724265738052193,-97.24945283742396,25,2
43,433,24.48713046908765,-97.59764743717052,26,2
59,442,25.35284441116698,-97.06032252207848,27,2
61,442,25.46141127997772,-97.05937801465758,28,2
62,444,25.514605007836384,-96.94003374232112,29,2
29,440,23.723846594719276,-97.19096992696834,30,3
43,434,24.486897474919978,-97.53876699838483,31,3
60,443,25.406603480942334,-97.00047511628769,32,3
62,441,25.516184831702166,-97.11834002241596,33,3
62,449,25.511327212479294,-96.64286546489153,34,3
")
wx_map <- mapdeck(data=NULL,token = Sys.getenv("MAPBOX_API_TOKEN"),style = 'mapbox://styles/mapbox/dark-v9',zoom = 6, location = c(-97,24.5))
observe({
wx_dt <- mydata %>% dplyr::filter(hr == input$hr)
mapdeck_update(map_id = "wx") %>%
add_scatterplot(data=wx_dt,lon = "Center.Longitude",lat = "Center.Latitude",radius = 15000,fill_colour = "vil_int_36",legend = TRUE,layer_id = "wxlyr",update_view = FALSE,focus_layer=FALSE)
})
output$wx <- renderMapdeck(wx_map)
}
shinyApp(ui, sr)
Notice how the range of color scale in the legend changes but the color of the dots stay almost the same. I want the color to represent the min-max of the entire data set (not just the hour) so that I can see change in intensity while stepping through each hour. Thank you.
Good question; you're right you need to create a manual legend so it remains static, otherwise it will update each time the values in the plot update.
The manual legend needs to use the same colours as the map. The map gets coloured by library(colourvalues). So you can use this to make the colours outside of the map, then use the results as the manual legend
l <- colourvalues::colour_values(
x = mydata$vil_int_36
, n_summaries = 5
)
legend <- mapdeck::legend_element(
variables = l$summary_values
, colours = l$summary_colours
, colour_type = "fill"
, variable_type = "category"
)
js_legend <- mapdeck::mapdeck_legend(legend)
Now this js_legend object is in the correct JSON format for the map to render it as a legend
js_legend
# {"fill_colour":{"colour":["#440154FF","#3B528BFF","#21908CFF","#5DC963FF","#FDE725FF"],"variable":["20.00","23.50","27.00","30.50","34.00"],"colourType":["fill_colour"],"type":["category"],"title":[""],"css":[""]}}
Here it is in your shiny
library(mapdeck)
library(shiny)
ui <- fluidPage(
fluidRow(sliderInput(inputId = "hr",label = "Hour",min = 1,max = 3,value = 1)),
fluidRow(mapdeckOutput(outputId = "wx"))
)
sr <- function(input, output, session) {
mydata <- read.table(header=TRUE, sep=",",text="
ROW,COL,Center Latitude,Center Longitude,vil_int_36,hr
28,439,23.669885449218786,-97.2498101160108,20,1
41,433,24.37845221074034,-97.59803936272704,21,1
59,441,25.35333762373948,-97.11966878019186,22,1
61,441,25.461905262766468,-97.11878391116397,23,1
62,443,25.515163854569053,-96.99946877404128,24,1
29,439,23.724265738052193,-97.24945283742396,25,2
43,433,24.48713046908765,-97.59764743717052,26,2
59,442,25.35284441116698,-97.06032252207848,27,2
61,442,25.46141127997772,-97.05937801465758,28,2
62,444,25.514605007836384,-96.94003374232112,29,2
29,440,23.723846594719276,-97.19096992696834,30,3
43,434,24.486897474919978,-97.53876699838483,31,3
60,443,25.406603480942334,-97.00047511628769,32,3
62,441,25.516184831702166,-97.11834002241596,33,3
62,449,25.511327212479294,-96.64286546489153,34,3
")
## create a manual legend
l <- colourvalues::colour_values(
x = mydata$vil_int_36
, n_summaries = 5
)
legend <- mapdeck::legend_element(
variables = l$summary_values
, colours = l$summary_colours
, colour_type = "fill"
, variable_type = "category"
)
js_legend <- mapdeck::mapdeck_legend(legend)
### --------------------------------
wx_map <- mapdeck(
style = 'mapbox://styles/mapbox/dark-v9'
, zoom = 6
, location = c(-97,24.5)
)
observe({
wx_dt <- mydata %>% dplyr::filter(hr == input$hr)
mapdeck_update(map_id = "wx") %>%
add_scatterplot(
data = wx_dt
, lon = "Center.Longitude"
, lat = "Center.Latitude"
, radius = 15000
, fill_colour = "vil_int_36"
, legend = js_legend
, layer_id = "wxlyr"
, update_view = FALSE
, focus_layer = FALSE
)
})
output$wx <- renderMapdeck(wx_map)
}
shinyApp(ui, sr)

Adding groupcheckboxinput values to data frame in Shiny

I am attempting to add the values from a checkboxgroupinput value to the data frame called surv_data in a Shiny App.
Below is the code for the check boxes:
checkboxGroupInput(inputId = "variables", label = "",
choices = c(
"Covariate 1" = "cov1",
"Covariate 2" = "cov2"
),
selected = c('cov1', 'cov2'))
Here is where I combine the variables in to one data frame:
surv_data <- reactive({
raw_surv <- raw_surv_data()
data.frame(
Time = raw_surv[[input$Time]],
Treatment = raw_surv[[input$Treatment]],
endpoint = raw_surv[[input$Endpoint]]
)
})
I need to somehow add the values cov1 and cov2 below the following line:
endpoint = raw_surv[[input$Endpoint]]
I've attempted to add variables = raw_surv[[input$variables]] but unfortunately this does not work. Any help would be appreciated.
Maybe
surv_data <- reactive({
raw_surv <- raw_surv_data()
cbind(
data.frame(
Time = raw_surv[[input$Time]],
Treatment = raw_surv[[input$Treatment]],
endpoint = raw_surv[[input$Endpoint]]
),
raw_surv[input$variables]
)
})

Resources