I have a DT data table which contain strings like below:
I want to change the colour of the cell, so that the cells with strings that contain "OK" will turn green, and cells with strings that contain "ERROR" will turn red. I know that I can change the cell colour by using formatStyle and styleEqual but it does not seem to work when matching string patterns.
library(DT)
render <- c(
"function(data, type, row){",
" if(type === 'display'){",
" var color = /OK$/.test(data) ? 'green' : (/ERROR$/.test(data) ? 'red' : 'black');",
" data = '<span style=\"color: ' + color + ';\">' + data + '</span>';",
" }",
" return data;",
"}"
)
dat <- data.frame(
a = c("1 - OK", "1 - ERROR", "2 - ERROR"),
b = c("3 - ERROR", "2 - OK", "3 - OK")
)
datatable(
dat,
options = list(
columnDefs = list(
list(targets = c(1, 2), render = JS(render))
)
)
)
Related
How can I render a text column containing the output of {sparkline}s' spk_chr() with {reactable}?
Note that I do not want to use the way described in the docs (https://glin.github.io/reactable/articles/examples.html), but explicitly use spk_chr() output.
Here is a reprex:
library(dplyr)
library(sparkline)
data <- chickwts %>%
count(feed)
summary_table <- data.frame(
x = "obs 1",
spark = spk_chr(
data$n,
barWidth = 500,
barSpacing = 100,
height = 50,
width = 300,
type = "bar",
tooltipFormatter = htmlwidgets::JS(
sprintf(
"function(sparkline, options, field){
debugger;
return 'value=' + %s[field[0].offset] + '<br/> n=' + field[0].value;
}",
jsonlite::toJSON(
data$feed
)
)
)
)
)
reactable(summary_table) #I want to render the spark column
I am trying to create an html table using the datatable function in the DT package so that when I sort the data in R markdown, missing rows are sorted after the highest number.
For example, in the following table, when I sort by "age" in the markdown file, I would like the row with NA to be listed last so that the order is 14,15,21,NA.
dat <- data.frame("Age" = c(21,15,NA,14),
"Name" = c("John","Dora", "Max", "Sam"),
"Gender" = c("M","F","M",NA))
DT::datatable(dat, filter = c("top"))
I have tried using "na.last = TRUE" and this works when the datatable initially prints, however when clicking the column to sort, NA is still before 14.
Any help would be much appreciated!
With the render columnwise option, you can set the value of the missing values during the sorting:
library(DT)
dat <- data.frame("Age" = c(21,15,NA,14),
"Name" = c("John","Dora", "Max", "Sam"),
"Gender" = c("M","F","M",NA))
render <- JS(
"function(data, type, row) {",
" if(type === 'sort' && data === null) {",
" return 999999;",
" }",
" return data;",
"}"
)
datatable(
dat,
filter = "top",
options = list(
columnDefs = list(
list(targets = 1, render = render)
)
)
)
I'm stuck in trying to pass the column name (instead the column number) in the target option of columnDefs. The table is dynamic so I definitely need the option to target the column name. Below is a reproducible example. The example is not dynamic, however.
datatable(iris[c(1:20, 51:60, 101:120), ], options = list(columnDefs = list(list(
targets = 5,
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data.length > 6 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 6) + '...</span>' : data;",
"}")
))), callback = JS('table.page(3).draw(false);'))
Tried with targets = 'Species' , targets = iris$Species but they didn't work.
if you are interested in setting multiple columns to different widths, consider the following (take care that R is one based, while javascript is one based):
col_a <- which(names(dat) %in% c("column_name1", "column_name2"))
col_b <- which(names(dat) %in% c("column_name3", "column_name4"))
col_c <- which(names(dat) %in% c("column_name5"))
columnDefs = list(list(width = '30px', targets = as.list(col_a - 1)),
list(width = '80px', targets = as.list(col_b - 1)),
list(width = '200px', targets = as.list(col_c - 1)))
I would like to explicitly show the Inf value inside a datatable instead of a blank
iris[1, 1] <- Inf
DT::datatable(iris[1:2, ])
I don't want to turn the column info character to be able to sort the column (If I do this, sorting will be alphabetically)
Any ideas?
Edit:
I thinks it's possible to adapt this kind of code :
datatable(iris[c(1:20), ], options = list(columnDefs = list(list(
targets = 5,
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data.length > 2 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 2) + '...</span>' : data;",
"}")
))))
with #MLavoie solution, it doesn't distinct NA and Inf
df = iris
df[1,1]<-Inf
df[2,1]<-NA
DT::datatable(df)
library(DT)
DT::datatable(df[,], options = list(columnDefs = list(list(
targets = 1,
render = JS(
"function(data, type, row, meta) {",
"return data === null ? 'Inf' : data;",
"}")
))))
The solution is :
options(htmlwidgets.TOJSON_ARGS = list(na = 'string'))
iris[1,1] <- NA
iris[2,1] <- Inf
DT::datatable(head(iris))
thanks to #yihui-xie and #Jeroen at : https://github.com/rstudio/DT/issues/496#issuecomment-363867449
You can do this:
df = iris
df[1,1]<-Inf
datatable(df[1:2,], options = list(columnDefs = list(list(
targets = 1,
render = JS(
"function(data, type, row, meta) {",
"return data === null ? 'Inf' : data;",
"}")
))))
and you could also do it manually:
DT::datatable(df[1:2,], editable = TRUE)
How can you add a tool tip to column header in a data table display
output$table <- renderDataTable({
df <- iris
colnames(df) <- sapply(names(df), function(x) abbreviate(x))
df
})
The actual data frame i'm using (which I can't show) has very long names and there are >20 columns. So abbreviating is necessary to show the entire data frame with minimal horizontal scrolling. I'm looking for a way to add a hover over tool tip that shows the full, un-abbreviated name of each column when you hover over an abbreviated column header.
dat <- iris[1:3,]
names(dat) <- c(
"A long name",
"Another long name",
"Yet another long name",
"This name is long as well",
"This one is not short"
)
headerCallback <- c(
"function(thead, data, start, end, display){",
" var ncols = data[0].length;",
sprintf(" var shortnames = [%s]",
paste0(paste0("'",abbreviate(names(dat)),"'"), collapse = ",")),
sprintf(" var tooltips = [%s];",
paste0(paste0("'",names(dat),"'"), collapse = ",")),
" for(var i=0; i<ncols; i++){",
" $('th:eq('+i+')',thead).attr('title', tooltips[i]).text(shortnames[i]);",
" }",
"}"
)
datatable(dat, rownames = FALSE,
options = list(
headerCallback = JS(headerCallback)
)
)