I'm trying to style my flextables programatically, but I ran into problems when using certain functions, for example merge_at()
and hline()
; they only style the very last entry of the column I'm referencing, no matter what row I try to use.
Here is a minimal example. iris_a
turns out to look like I want it to, while iris_b
is changed in a way I can't comprehend.
# setup
library(tidyverse)
library(officer)
library(flextable)
thin_border <- fp_border(color = "gray")
setosa <- iris %>% group_split(Species) %>% .[[1]] %>% slice(1:2)
versicolor <- iris %>% group_split(Species) %>% .[[2]] %>% slice(1:2)
iris_a <- bind_rows(setosa, versicolor) %>% mutate(spec = case_when(
Species == "setosa" ~ "set",
Species == "versicolor" ~ "versi"
)) %>% flextable()
iris_b <- iris_a
specs <- c("setosa", "versicolor")
# actual transformation
for (k in specs) {
iris_a<- iris_a%>% hline(., i = ~ Species == k, j = 1:5, border = thin_border)
}
for(k in specs){
iris_a <- iris_a %>% merge_at(., i = ~ Species == k, j = ~spec)
}
iris_a %>% fix_border_issues()
# success, a nice table; now I wrap the loops into functions
merge_cells <- function(flex, location){
for(k in location){
flex <- flex %>% merge_at(., i = ~ Species == k, j = ~spec)
}
flex
}
add_vlines <- function(flex, location){
for (k in location) {
flex <- flex %>% hline(., i = ~ Species == k, j = 1:5, border = thin_border)
}
flex
}
iris_b <- iris_b %>%
add_vlines(., "set") %>%
merge_cells(., "set")
iris_b %>% fix_border_issues()
It doesn't matter to what location
is set, the outcome is the same (eg location = specs
).
I also tried to tackle this issue with mk_par()
but to no avail.
Where did I go wrong?
addendum: forgot to add, location
can be set to anything, the outcome is still the same (iris_b %>% merge_cells(., "something")
).
I think this will help you fix your issue. Your formula is the issue. I reduced the example to a simpler case.
library(flextable)
dat <- structure(list(Sepal.Length = c(5.1, 4.9, 7, 6.4), Sepal.Width = c(3.5,
3, 3.2, 3.2), Petal.Length = c(1.4, 1.4, 4.7, 4.5), Petal.Width = c(0.2,
0.2, 1.4, 1.5), Species = structure(c(1L, 1L, 2L, 2L), levels = c("setosa",
"versicolor", "virginica"), class = "factor"), spec = c("set",
"set", "versi", "versi")), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame"))
merge_cells <- function(flex, location){
for(k in location){
form <- as.formula(paste0("~ spec %in% '", k, "'"))
flex <- merge_at(flex, i = form, j = ~spec)
}
flex
}
flextable(dat) |> merge_cells(location = "set")