How to target specific columns with DT's SearchPanes extension - r

I want to implement DT's SearchPanes extension while explicitly including/excluding specific fields but am not sure how to accomplish it. I want all of the fields to show, but only select fields to be included in the SearchPanes interface.
In the reproducible example below (which is essentially from the documentation), how would I select just island, sex, and year for inclusion in SearchPanes?
I've tried different settings with searchPanes and the targets arguments, but I do not understand how to use these and I don't yet follow the JS documentation very well. Any guidance on how these work and how to select columns for inclusion would be much appreciated.
library(DT)
library(palmerpenguins)
datatable(
penguins,
options = list(dom = 'Pfrtip', columnDefs = list(list(
searchPanes = list(show = FALSE), targets = 1:4
))),
extensions = c('Select', 'SearchPanes'),
selection = 'none'
)

There may be a better way but this works:
datatable(
penguins,
options = list(
dom = 'Pfrtip',
columnDefs = list(
list(
searchPanes = list(show = FALSE), targets = c(1, 3:6)
),
list(
searchPanes = list(show = TRUE), targets = c(2, 7:9)
)
)
),
extensions = c('Select', 'SearchPanes'),
selection = 'none'
)
The searchPanes argument show can be set to TRUE or FALSE and the state is directed to specific target columns defined in the targets argument.
On one line, I set show=FALSE and defined all of the columns that I did not want showing. Then on the following line, I set showTRUE and defined the columns that I want showing. I found that if I set a column to show=FALSE and in the next line set it to show=TRUE it remains unshown.
The DataTables JS library documentation was helpful, but took a bit to understand. The section on columns.searchPanes.show contained the answer. Each searchPanes statement has some arguments and a set of targets. As follows:
$(document).ready(function() {
$('#example').DataTable({
dom: 'Plfrtip',
columnDefs: [
{
searchPanes: {
show: true
},
targets: [0]
},
{
searchPanes: {
show: false
},
targets: [2]
}
]
});
});

Related

R Knitr Why is the cache invalidated by copying?

Question
It seems the knitr cache becomes invalidated by copying the relevant files (.rmd script and cache directory) to another computer.
Why is that so and
how can I work around this?
Details
I do various lengthy calculations on two computers. I thought the following procedure could work:
Knit a first version of a report on machine A. (includes some lengthy calculations)
Copy the files created, i.e. the script and the cache directory, to machine B.
Continue editing the report on machine B (without recalculations because everything is cached).
This does not work, after copying the files to B, "knit" performs a full recalculation. This is even the case before any editing of the script was performed, i.e. just the act of copying from A to B seems enough to invalidate the cache.
Why is a full recalculation on B performed? As I understood it the caching mechanism boils down to creating and comparing a hash. I had hoped that after copying the hash would remain unchanged.
Is there something else I should copy in addition? Or is there any other way I can make the procedure above work?
Example
Any trivial script works as an example such as the one below:
```{r setup, include=FALSE}
knitr::opts_chunk$set(cache = TRUE)
```
Bla Bla
```{r test}
tmp = sort(runif(1e7))
```
I don't know the details of why that happens, but the workaround is easy: save values to files explicitly, and read them back in. You can use
saveRDS(x, "x.rds")
to save the variable x to a file named x.rds, and then
x <- readRDS("x.rds")
to read it back in. If you want to get fancy, you can check for the existence of x.rds using file.exists("x.rds") and do the full calculation followed by saveRDS if that returns FALSE, otherwise just read the data.
EDITED TO ADD: If you really want to know the answer to your first question, one possible approach would be to copy the folder back from the 2nd computer to the 1st, and see if it works back there. If not, do a binary compare of the original and twice copied directories and see what has changed.
If it does work, it might simply be different RNGkind() settings on the two computers: it's pretty common to have the buggy sample.kind = "Rounding" saved. Not sure that caching would use this. Or perhaps different package versions or R versions: when I updated knitr the cache was invalidated.
MORE additions:
If you want to see what has changed, then turn on debugging on the digest::digest function, and call knitr::knit("src.Rmd"). digest() is called for each cached chunk, and passed a large list in its object argument. It should return the same hash value if the list is the same, so you'll want to save those objects, and compare them between the two computers. For example, with your toy example above, I get this passed as object:
list(eval = TRUE, echo = TRUE, results = "markup", tidy = FALSE,
tidy.opts = NULL, collapse = FALSE, prompt = FALSE, comment = "##",
highlight = TRUE, size = "normalsize", background = "#F7F7F7",
strip.white = TRUE, cache = 3, cache.path = "cache/", cache.vars = NULL,
cache.lazy = TRUE, dependson = NULL, autodep = FALSE, fig.keep = "high",
fig.show = "asis", fig.align = "default", fig.path = "figure/",
dev = "png", dev.args = NULL, dpi = 72, fig.ext = NULL, fig.width = 7,
fig.height = 7, fig.env = "figure", fig.cap = NULL, fig.scap = NULL,
fig.lp = "fig:", fig.subcap = NULL, fig.pos = "", out.width = NULL,
out.height = NULL, out.extra = NULL, fig.retina = 1, external = TRUE,
sanitize = FALSE, interval = 1, aniopts = "controls,loop",
warning = TRUE, error = TRUE, message = TRUE, render = NULL,
ref.label = NULL, child = NULL, engine = "R", split = FALSE,
purl = TRUE, label = "test", code = "tmp = sort(runif(1e7))",
75L)

Best practices for drake pipeline experimentation

I'm new to drake but loving it so far. One thing I'm having trouble with is how to best go about experimenting with different pipeline configurations. That is, my plans consist purely of a chain of targets where the output from the first target is the input for the second, the second forms the input for the third, etc. My targets all have the same basic structure (dynamic targets with tibbles as individual entries) expected as input and supplied as output, and I want to experiment with different orderings, inclusion/exclusion of certain steps, etc. For example:
plan = drake::drake_plan(
a_transformed = target(
compute_a_transform(list_of_input_data)
, dynamic = map(list_of_input_data)
)
, b_transformed = target(
compute_b_transform(a_transformed)
, dynamic = map(a_transformed)
)
, c_transformed = target(
compute_c_transform(c_transformed)
, dynamic = map(c_transformed)
)
)
The way I've been using drake so far is that each target has a unique/meaningful name, so when I, for example, remove a target, I have to rename the input supplied to the subsequent target:
plan = drake::drake_plan(
a_transformed = target(
compute_a_transform(list_of_input_data)
, dynamic = map(list_of_input_data)
)
#, b_transformed = target(
# compute_b_transform(a_transformed)
# , dynamic = map(a_transformed)
#)
#note the b-transform step has been removed (commented-out), requiring inputs to c_transform to be changed from `b_transform` to `a_transform`
, c_transformed = target(
compute_c_transform(a_transformed) #had to rename things here
, dynamic = map(a_transformed) #and here
)
)
Would it be too much to hope that there's a better way of experimenting that doesn't require this manual commenting-out and renaming?
I worked out a method that is a bit of a hack but works for me. I simply add a skip argument to each function that triggers return of the input if TRUE:
compute_a_transform = function(x,skip=F){
if(skip){
return(x)
}
... #regular compute_a_transform stuff here
}
Then, when I want to skip a step in the processing chain, I simply set skip=TRUE without commenting-out or renaming anything
plan = drake::drake_plan(
a_transformed = target(
compute_a_transform(list_of_input_data)
, dynamic = map(list_of_input_data)
)
, b_transformed = target(
compute_b_transform(a_transformed, skip=TRUE) #skip=TRUE means the b-transform isn't actually applied
, dynamic = map(a_transformed)
)
, c_transformed = target(
compute_c_transform(c_transformed)
, dynamic = map(c_transformed)
)
)

Column selection and further plotting of filtered data from datatable (DT) in Shiny

I have two questions about datatable (DT) in Shiny and
till this moment i could not find an any answer.
I would like to select column instead of a row in datatable -->
I have tried (as it was written on official website http://rstudio.github.io/DT/shiny.html):
datatable(..., selection = list(target = 'column'))
in my code::
datatable(data[, c("Datum", "Kunde", "Block.Nr.", "Toleranz",
"Kaliberschema")], class = 'cell-border stripe',
rownames=FALSE, filter="top", selection = list(target = 'column'), options = list(lengthChange = FALSE, columnDefs = list(list(width = '200px', targets = "_all"), list(bSortable = FALSE, targets = "_all"))), callback=JS("
//hide column filters for two columns
$.each([0, 1], function(i, v) {
$('input.form-control').eq(v).hide()});",
"var tips = ['Datum von..bis', 'Kunde', 'Block.Nr.',
'Toleranz +', 'Kaliberschema'],
header = table.columns().header();
for (var i = 0; i < tips.length; i++) {
$(header[i]).attr('title', tips[i]);}")) %>%
formatStyle("Datum", color = 'red', backgroundColor = 'lightyellow', fontWeight = 'bold')})
This code was not working at all, just got an error:
Error in match.arg(selection) : 'arg' must be NULL or a character vector
Than i have tried inside an options smthg like this:
options = list(target = 'column', lengthChange = FALSE, columnDefs = list(list(width = '200px', targets = "_all")...
It was as well not working...
Does anyone have any ideas??
2nd Thing is that i would lke to use this selected column to plot a line plot and histogram using ggplot.
Thanks in advance for any ideas
Are you using the latest development version of DT available from github or the 2015 v0.1 package release from CRAN? Your error indicates the latter; the selection options you have chosen might simply not be available. For installation from github, you may install the devtools package from CRAN and proceed via library(devtools);install_github("rstudio/DT"). Or even better: ask the authors when the package becomes available via CRAN, as this sort of confusion has come up elsewhere ...

Shiny Column rendering error

This is a Q on the Column rendering example (4.4)provided in this link.
http://rstudio.github.io/DT/options.html
I have implemented the example code described above to abbreviate character strings that are wider than 100 characters using the first 100 characters plus an ellipsis (…), and the full character string is displayed as a tooltip when you mouse over the cell. This works well as long as the column with custom rendering has full text in it. However, when it encounters an empty cell the table is not displayed and it shows " Processing..." on shiny browser. On disabling this custom rendering I am able to display the table with empty fields as expected.
Did anyone had similar issue, any suggestion to overcome this ?
Below is my custom column rendering code.
output$PM_output <- DT::renderDataTable(
expr = DT::datatable(PubmedOutput(PubmedSearch()),
class = 'cell-border stripe compact hover',
escape = F, selection = 'multiple',
options = list(
initComplete = JS("function(settings, json) {",
"$(this.api().table().header()).css({
'background-color': '#303030',
'color': '#FFFF00'});","}"),
autoWidth = T,
LengthMenu = c(5, 30, 50),
columnDefs = list(list(
targets = 6,
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data.length > 100 ?",
"'<span title=\"' + data + '\">' +
data.substr(0, 100) + '...</span>' : data;", "}"))),
columnDefs = list(list(
targets = c(1:8),
className = 'dt-center')),
pageLength = 1, server = T)))
The code that generate the Column 6 that I have passed custom rendering on.
PM.ID <- c("26391251","26372702","26372699","26371045") # does not output table
fetch.pubmed <- entrez_fetch(db = "pubmed", id = PM.ID,
rettype = "xml", parsed = T)
abstracts = xpathApply(fetch.pubmed, '//PubmedArticle//Article', function(x) xmlValue(xmlChildren(x)$Abstract))
abstracts # ID 26372702, 26372699 has no abstract. and returns NA
Any inputs and suggestion.
P.S: Is there a better way to display data other than ellipsis/ tooltip ?
the code is too big to paste it all, hence picking only the parts where I noticed the issue. I hope it helps.
The condition data.length > 100 is not enough: you need to make sure data is a character string first. In your case, data may be null (converted from R's NA to JavaScript), and null.length will trigger an error. Replace
type === 'display' && data.length > 100
with a more rigorous condition:
type === 'display' && typeof data === 'string' && data.length > 100

DT conditional formatting for column

I need some help with conditional formatting for DT::datatable. I would like to highlight a couple of names in the following example by printing them in italics. The names which need to be highlighted are in a vector name.highlight <- c("ABC","JKL")
require(DT)
mydf <- data.frame(name=c("ABC","DEF","GHI","JKL","MNO","PQR"), value=1:6)
DT::datatable(mydf)
Based on what I see here and here, seems like I need to use render. I have no idea how to write the JS code or how I can pass in a vector/container with all the strings which need to be highlighted.
datatable(mydf, options = list(columnDefs = list(list(
targets = 0, render = JS("function(data, type, full, meta) {", ..., "}")
))))
Thanks.
datatable(mydf, options = list(columnDefs = list(list(
targets = 0, render = JS(
"function(data, type, full, meta) {",
"italic_words=['ABC','JKL']",
"return type === 'display' && italic_words.indexOf(data) != -1 ?",
"'<i>'+data+'</i>' : data;",
"}")
))))
I defined the italic_words variable in the javascript function. The variable contains an array of all the words you want in italic. Then I used the indexOf() javascript function. If the name isn't in the variable italic_words, this function will return -1, and the name will not be italicized.

Resources