flextable package assigns changes without <- - r

I'm not sure if this is the correct forum to post this, but I have noticed some strange behavior with the flextable package in R, and was wondering if anyone can shed any light.
In the documentation for flextable it shows objects being modified when they are re-assigned to themselves, eg:
ft <- regulartable(head(iris))
ft <- color(ft, color = "orange", part = "body" )
However, my code is modifying the actual table even without re-assigning it, just using piping %>%:
myft <- regulartable(head(iris))
myft %>% align(j = 1, align = "left")
myft # changed
I don't think piping is the issue as it doesn't have the same effect with other packages, eg:
library(plyr)
df <- head(iris)
df %>% mutate(Sum=Sepal.Width*2)
df # unchanged
Is this a bug in flextable? Or is this by design?

It's true that you can mutate formats without assigning the object. But that's not a behavior you can rely on. This is an unwanted design ;) and should be corrected in the next versions so it is safer to assign the result if you want your code to work with future versions.

Related

How to create a string that can be used as LHS and assigned a value to?

I feel stupid for asking such a simple question, but I am hitting my head in the wall.
Why does the paste0() create a string that cannot be not interpreted as name for an empty object ? Is there a different way of create the LHS that would be better?
As input I have a dataframe. As an output I want to have a new filtered dataframe. This works fine as long as I manually type all the code. However, I am trying to reduce repetition, and therefore I want to create a function that does the same thing, but then it is not working anymore.
library(magrittr)
df <- data.frame(
var_a = round(runif(20), digits = 1),
var_b = sample(letters, 20)
)
### Find duplicates
df$duplicate_num <- duplicated(df$var_a)
df$duplicate_txt <- duplicated(df$var_b)
df # a check
### Create two lists of duplicates
list_of_duplicate_num <-
df %>%
filter(duplicate_num)
list_of_duplicate_num # a check
list_of_duplicate_txt <-
df %>%
filter(duplicate_txt)
list_of_duplicate_txt # a check '
So far everything works as expected.
I would like to simplify the code and make this to a function that takes the arguments "num" or "txt". But I am having problems with creating the LHS.
The below should, in my mind, do the same as the code above.
paste0("list_of_duplicate_", "num") <-
df %>%
filter(duplicate_num)
I do get an error message:
Error in paste0("list_of_duplicate_", "num") <- df %>%
filter(duplicate_num) :
target of assignment expands to non-language object
My goal is to create a function with something like this:
make_list_of_duplicates <- function(criteria = "num") {
paste0("list_of_duplicate_", criteria) <-
df %>%
filter(paste0("duplicate_", criteria))
paste0("list_of_duplicate_", criteria) # a check
}
### Create two lists of duplicates
make_list_of_duplicates("num")
make_list_of_duplicates("txt")
and then continue with some joins etc.
I have been looking to tidy evaluation, assignments, rlang::enexpr(), base::substitute(), get(), mget() and many other things, but after two day of reading and trial and error, I am convinced that there must be a an other direction to look at that I am not seeing.
I am running MS Open R 4.0.2.
I am grateful for any suggestions.
Sincerely,
Eero
I found the solution to my question, when I understood that it was a case of indirection. Because I was on a wrong track, I created lots of complications and made it more difficult than necessary. Thanks to #r2evans who pointed me in the right direction. I have in the mean time decided that I will use loops, instead of functions, but here is the working function:
## Example of using paste inside a function to refer to an object.
library(magrittr)
library(dplyr)
df <- data.frame(
var_a = round(runif(20), digits = 1),
var_b = sample(letters, 20)
)
# Find duplicates
df$duplicate_num <- duplicated(df$var_a)
df$duplicate_txt <- duplicated(df$var_b)
# SEE https://dplyr.tidyverse.org/articles/programming.html#indirection-2
make_list_of_duplicates_f2 <- function(criteria = "num") {
df %>%
filter(.data[[paste0("duplicate_", {{criteria}})]])
}
# Create two lists of duplicates
list_of_duplicates_f2_num <-
make_list_of_duplicates_f2("num")
list_of_duplicates_f2_txt <-
make_list_of_duplicates_f2("txt")

how to save r dataframe as an image

How can I create an image from a data frame? For example:
library(tidyverse)
library(gridExtra)
df = iris %>% slice(1:4)
I've the following but:
1. I haven't been able to get this to be saved to a variable. It just pops up in the plots pane of Rstudio. Am I missing something obvious? I'd like to be able to have this plot referenced to a variable so I could save it as a png or something.
2. Is there a way to remove the row numbers that seem to appear?
3. This look is fine, but is there a way to make it more of a lighter background compared to what this is?
gridExtra::grid.table(df)
To save a relevant variable, use
myTable <- tableGrob(df)
since
grid.table
# function (...)
# grid.draw(tableGrob(...))
# <bytecode: 0x10758c078>
# <environment: namespace:gridExtra>
Given that, you can run
library(grid)
grid.draw(myTable)
For that you want
myTable <- tableGrob(df, rows = NULL)
See ?tableGrob and particularly ttheme_default (its source code makes pretty clear what are possible parameters; see also here). For instance,
myTable <- tableGrob(
df,
rows = NULL,
theme = ttheme_default(core = list(bg_params = list(fill = "grey99")))
)
grid.draw(myTable)

dplyr table display style change [duplicate]

Using the latest version of tibble the output of wide tibbles is not properly displayed when setting width = Inf.
Based on my tests with previous versions wide tibbles were printed nicely until versions later than 1.3.0. This is what I would like the output to be printed like:
...but this is what it looks like using the latest version of tibble:
I tinkered around with the old sources but to no avail. I would like to incorporate this in a package so the solution should pass R CMD check. When I just copied a load of functions from tibble v1.3.0 I managed to restore the old behavior but could not pass the check.
There's an open issue on Github related to this problem but it's apparently 'not high priority'. Is there a way to print tibbles properly with the new version?
Try out this function:
print_width_inf <- function(df, n = 6) {
df %>%
head(n = n) %>%
as.data.frame() %>%
tibble:::shrink_mat(width = Inf, rows = NA, n = n, star = FALSE) %>%
`[[`("table") %>%
print()
}
This seems to have change, now one can just use:
options(tibble.width = Inf)

Print tibble with column breaks as in v1.3.0

Using the latest version of tibble the output of wide tibbles is not properly displayed when setting width = Inf.
Based on my tests with previous versions wide tibbles were printed nicely until versions later than 1.3.0. This is what I would like the output to be printed like:
...but this is what it looks like using the latest version of tibble:
I tinkered around with the old sources but to no avail. I would like to incorporate this in a package so the solution should pass R CMD check. When I just copied a load of functions from tibble v1.3.0 I managed to restore the old behavior but could not pass the check.
There's an open issue on Github related to this problem but it's apparently 'not high priority'. Is there a way to print tibbles properly with the new version?
Try out this function:
print_width_inf <- function(df, n = 6) {
df %>%
head(n = n) %>%
as.data.frame() %>%
tibble:::shrink_mat(width = Inf, rows = NA, n = n, star = FALSE) %>%
`[[`("table") %>%
print()
}
This seems to have change, now one can just use:
options(tibble.width = Inf)

How to set highchart global options IN R

I see a lot of examples in javascript but I cannot find an example to do it in R
Here is the api link: http://api.highcharts.com/highcharts#global
I am trying to set "timezoneOffset" and I have tried many different ways.
When I do this in R: highChart$global(timezoneOffset=-300)
I do not get any warning or error, but it's not working.
Thanks a lot for the help!
Here is a piece of code:
library(rCharts)
highChart <- Highcharts$new()
highChart$global(timezoneOffset=-300)
highChart$chart(zoomType = "xy")
highChart$exporting(enabled = T)
highChart$xAxis(type="datetime",list( title = list(text = "Time")))
highChart$yAxis(list
(
list(title = list(text = "Variance"))
))
highChart$series(data=list(c(x=1407795845000,y=1),c(x=1407795846000,y=2),c(x=1407795847000,y=3)))
highChart
As you can see, the timezoneOffset is not working when I run this piece of code and the time is still displayed in GMT.
As of version 0.5.0 of highcharter, it seems the option highcharter.options is not there any more, but there are several separate options, e.g. highcharter.lang, highcharter.global, etc. So the following approach works:
lang <- getOption("highcharter.lang")
lang$decimalPoint <- ","
lang$numericSymbols <- highcharter::JS("null") # optional: remove the SI prefixes
options(highcharter.lang = lang)
In addition to changing the decimal point, the SI prefixes ("k", "M", "G", etc.) are turned off by setting the numericSymbols to null, see Replacing/removing the metric notations like thousands "k" abbreviation.
The highcharter options can be accessed, but they are set inside the standard R options under the list element highcharter.options. They are not given directly to the highchart, and inside highchart(), there is the code line opts <- getOption("highcharter.options", list()).
I don't think there is another way than just get the options, alter whatever options you need to change and then set the options again with your additions.
The following is a simple illustration:
library(highcharter)
# normal highchart
highchart() %>%
hc_add_serie_labels_values(1:901, seq(1, 10, 0.01))
opts <- getOption("highcharter.options")
opts$lang$decimalPoint <- "."
options(highcharter.options = opts)
# now with "," instead of "." (confirm in tooltip)
highchart() %>%
hc_add_serie_labels_values(1:901, seq(1, 10, 0.01))
Of course in your case, you need to set the $global$timezoneOffset part.
First you have to switch of the useUTC flag to FALSE. Than you can set the timezoneOffset as you wish and save the options back.
global <- getOption("highcharter.global")
global$useUTC <- FALSE
global$timezoneOffset <- -300
options(highcharter.global = global)
For better understanding make sure you take a look at global:
str(global)

Resources