zeehio / condformat Goto Github PK
View Code? Open in Web Editor NEWR package to apply conditional formatting rules to a data.frame
License: Other
R package to apply conditional formatting rules to a data.frame
License: Other
Currently only html output is possible.
To add LaTeX output we need to "translate" css to latex instructions.
Assume we have:
In the HTML case we are:
For the LaTeX syntax this approach is not good, as formatting wraps values (\textbf{value}
for bold).
function(value) sprintf("\\textbf{%s}", value)
.x
here with the call of the proper lambda function to the right value (with a mapply
call to iterate along all lambdas and values). myfun <- function(fun, y) return fun(y)
and then `mapply(FUN=myfun, matrix_of_lambdas, values). The idea is to obtain a matrix of characters with the LaTeX code for each formatted element.Hi,
If I am exporting data frames to excel, can I show the currency and percentage symbols in the excel spreadsheet on certain columns ($, %)?
Cheers!
When attempting to use this line of code,
condformat::condformat2excel(cf, "hello.xlsx",,T)
I get the following traceback.
6: stop(gettextf("'%s' is not an exported object from 'namespace:%s'", name, getNamespaceName(ns)), call. = FALSE, domain = NA)
5: getExportedValue(pkg, name)
4: xlsx::CellBlock.default
3: condformat2excelsheet(x, sheet)
2: condformat::condformat2excel(cf, "hello.xlsx", , T) at transcriptome_pharmer.r#363
1: heatMapper(geneDF)
This package is awesome, but I've noticed something that may be a bug.
When knitting to PDF, ## NULL
appears before the table output. Apparently, this does not happen when knitting to HTML, per comments in this StackOverflow thread I created.
Could you please take a look?
Note: Please see code in StackOverflow question, as the RMD chunk delimiters aren't working with GitHub's code delimiters.
Hi,
condformat works as intended without a loop, but strangely enough breaks when wrapped in one (I'd like to use it for large tables). I've put together a minimal example at:
https://tex.stackexchange.com/questions/516747/for-loop-breaks-condformat
Cheers.
Check the following case and output:
# Custom discrete color values can be specified with a function. The function takes
# the whole column and returns a vector with the colours.
color_pick <- function(col) {
ifelse(col < 4.7,
"yellow",
ifelse(col < 4.9,
"orange",
"purple"))
}
condformat(head(iris)) + rule_fill_discrete_("Sepal.Length", ~ color_pick(Sepal.Length))
In other words, it appears the thresholds are being respected, but the colors being passed are not.
Apart from LaTeX and HTML, it would be cool to have a condformat2grob
function that creates a plot with the formatted table. This would be the fallback for any other output that does not accept HTML or LaTeX (for docx, github_document and others)
Hi, I was wondering whether you had thought about providing a function to allow this to be used in Shiny Apps. So we would need some kinda renderCondformat
for the server.R and then a condformatOutput
for the ui...
Have you thought about this?
I am using condformat package to color each coloumn of a dataframe. I am able to do single column but don't know how to apply for all columns without using colnames (as they change dynamically)
I used the following code to achieve conditional column coloring for single column
data(iris)
library(condformat)
dat<-iris[c(1:5,70:75, 120:125),]
condformat(dat) %>%
rule_fill_discrete(Sepal.Width,
expression = Sepal.Width > Petal.Length)
The above code changes the color of the column (sepal.width) successfully. But what I want is to apply the same condition for all columns (for example c(1:5) where without knowing the column names. I tried like . and x etc. but nothin
Hi, take a look here: http://stackoverflow.com/questions/41402379/how-can-i-pass-character-strings-as-independent-parameters-after-a
Perhaps the functions being exposed by Gregor and by myself (Amit Kohli) could be useful inclusions to this packet.
The only addition I could think of could be to extend the function to accept inputs for thresolds and colors. Something like:
I'm close with this:
color.picker <- function(z) {
if (is.na(z)) { return(0)
} else if (z < 5) { return(1)
} else if (5 >= z & z < 10) { return(2)
} else { return(3)
}
}
CondFormatForInput2 <- function(Table,VectorToColor,VectorFromColor) {
cf <- condformat(Table)
input = data.frame(Val=VectorToColor,Comp=VectorFromColor)
fills2_ = purrr::map2(input$Val,.y = input$Comp,.f = function(x,y) rule_fill_discrete_(x, expression =
sapply(Table[[y]],color.picker),colours = c(`0` = "white", `1` = "red",`2` = "lightyellow", `3` = "lightgreen")))
res_ = Reduce(f = "+", x = fills2_, init = cf)
res_
}
CondFormatForInput2(iris,
c("Petal.Width","Petal.Length"),
c("Petal.Width","Petal.Width"))
But there's two problems with my approach: 1) the parameter that decides the color is somehow Column 1 (in the xample above it's the Sepal.Length) rather than whatever I'm passing as y 2) This is still messy... I'm passing the sapply portion w/ the colors in the call, not in the color.picker
function... which is messy and weird.
I think this would be really cool if the color.picker
function accepted a df as input, with column 1 being the thresholds, and column 2 the colors... and then passing that modified color.picker
function to the map2
command in CondFormatForInput2
.
What do you think?
Hey,
It would be cool if this package were updated to support the recently added shiny async render functions. At the moment, renderCondformat() does not handle promises.
Here is a minimal repro:
library(shiny)
library(future)
library(promises)
library(condformat)
library(dplyr)
ui <- fluidPage(
actionButton("execute", "Execute"),
helpText("The synchronous table output"),
condformatOutput("sync_table"),
helpText("The asynchronous table output"),
condformatOutput("async_table")
)
server <- function(input, output) {
our_sync_data <- reactive({
input$execute
data.frame(type = c(rep("A", 5), rep("B", 5)),
n = seq(1,100,10))
})
our_async_data <- reactive({
input$execute
future({
data.frame(type = c(rep("A", 5), rep("B", 5)),
n = seq(1,100,10))
})
})
output$sync_table <- renderCondformat({
our_sync_data() %>%
condformat() %>%
rule_fill_discrete(type, expression = n <= 50,
colours = c("TRUE" = "yellowgreen", "FALSE" = "tomato"))
})
output$async_table <- renderCondformat({
our_async_data() %...>%
condformat() %...>%
rule_fill_discrete(type, expression = n <= 50,
colours = c("TRUE" = "yellowgreen", "FALSE" = "tomato"))
})
}
shinyApp(ui, server)
And here is the output of sessionInfo():
> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.4
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib
locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] promises_1.0.1 dplyr_0.7.4 condformat_0.7.0 future_1.8.1 shiny_1.0.5
Thank you!
Hi,
I'd like to color different columns in the xlsx that I create, by using several rules for the fill gradient.
Everything looks nice in the R Studio Viewer, but any then the firat rule_fill_gradient seem to be ignored by condformat2excel.
When e.g. doing the following, only column 1 is colored with a green gradient...
output <- condformat(df4) + rule_fill_gradient(1, expression = overall_score, low = "white", high = "green", na.value = "#FFFFFF") + rule_fill_gradient(2, expression = overall_score, low = "white", high = "red", na.value = "#FFFFFF")
condformat2excel(output, output.xlsx)
Current render2excel function only accepts a parameter for workbook name
.
Can you add a parameter for sheetname
as the current default of sheet1 is not accessible and therefore I am not able to loop through a series of tables that I need to export.
myTable <- condformat(iris[c(1:5, 70:75, 120:125), ]) +
rule_fill_discrete(Species, colours = c("setosa" = "red",
"versicolor" = "blue",
"virginica" = "green")) +
rule_fill_discrete(Sepal.Length, expression=Sepal.Length > 4.6,
colours=c("TRUE"="red"))
condformat2latex(myTable)
Currently there is not a legend system implemented describing the conditional formatting rules.
For instance in:
data(iris)
library(condformat)
condformat(iris) + scale_fill_discrete(Species)
The legend would have three rows, all empty but in the Species column, showing the three possible values with their colour.
data(iris)
library(condformat)
condformat(iris) + scale_fill_discrete(Species, expression = Sepal.Length > 3.5, c("TRUE" = "red"))
The legend here would have two rows. The rows would only be filled in the Species column having as text the expression == TRUE
(or FALSE), formatted in red or whatever.
With gradients, showing the extremes would be fine.
I note that when I call condformat2grob
the plot is immediately generated and displayed, even if what I'm trying to do is to store the grob in a variable for layout with ggarrange
or grid.arrange
. In my case, where I have two conditionally formatted tables and one ggplot layed out with ggarrange
, this causes knitr to output first the one table, then the second one, and then the composite figure (which itself is just fine).
I seem to have fixed this myself by altering the source code -- I commented out two function calls right at the end of the condformat2grob
function: grid::grid.newpage()
and grid::grid.draw(gridobj)
. The subsequent call (invisible(gridobj)
) seems to return the grob properly, and my ggarrange
layout works as it should.
Knocking out these two lines probably messed up something elsewhere (so not going to make a PR out of this), but for my purposes it works perfectly. Thanks for your work on this -- it's fantastic!
Hi,
Just wanted to say thank you, have been using the condformat package a lot with much success! On the recent release of version 0.9.0 I am encountering the following error when overwriting an existing xlsx workbook.
Warning: Error in openxlsx::saveWorkbook: File already exists!
Any help is much appreciated.
Once 0.7.0 is accepted and binaries are out there, follow http://r-pkgs.had.co.nz/release.html to finish the release steps
Or alternatively without having to explicitly name each column? I'm working on a shiny app and depending on the user selection the table and column names change. Thanks for your time.
I need to test the behaviour for:
print(condformat(head(iris)))
knit_print(condformat(head(iris)))
condformat(head(iris))
at the end of a blockAnd:
When knitr 1.18 is released update condformat:::guess_output_format
leveraging on exported functions: rstudio/rmarkdown#649
cf <- condformat(data[1:nrow(data),]) %>%
rule_text_color(col1,
expression = ifelse(col1 < col2 | col1 > col3, "red", ""))
%>%
rule_text_color(col4,
expression = ifelse(col4 < col5 | col4 > col6, "red", ""))
condformat:::condformat2excelsheet(cf, wb, "Sheet1")
saveWorkbook(wb, file = "formatted_file.xlsx", overwrite = TRUE)
This doesn't seem to be working. Would appreciate some help!
Please use parse_quo()
instead.
Can condformat handle "invalid" column names?
I tried some using:
myvar = "invalid col name %"
as.name(myvar)
but that leads to a parse error. Can I change colnames after the condformat()
statement? What's the best way to do this?
Thanks, Eric.
Is there any way to change from the default of 10 rows per page to some other value in the code (rather than changing the value once the table is produced?)
Hi,
I am the author of the openxlsx package. With the new version some of the test in your package fail.
Could you please check the dependencies?
If you have questions please feel free to contact me.
This is a feature request ;).
It would be nice to be able to control the tabulation (and page size) in shiny as well. I see that there is a parameter tabulate in the print function, however I haven't been able to force this form renderCondformat.
I want to create a rule that applies to several columns and make the expression dependant on the column where it is applied.
Proposed syntax:
condformat(iris) %>%
rule_fill_discrete(c(Sepal.Length, Sepal.Width), .col > 3)
Equivalent to:
condformat(iris) %>%
rule_fill_discrete(Sepal.Length, Sepal.Length > 3) %>%
rule_fill_discrete(Sepal.Width, Sepal.Width > 3)
All tests that use suggested packages should check to make sure the package is installed.
(This helps with revdepcheck)
Thank you,
Barret
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.