Remove a flextable columns after the flextable creation
Asked Answered
B

4

11

I create a flextable based on a csv file, I put some style on it, change some cells. Then I would like to remove a specific columns of this flextable before add it to a doc. Is-there a way to create a copy of a flextable and specifying col_keys?

mydf <- GetData(....)
cols <- names(mydf)
myft <- flextable(mydf, col_keys = cols)
# Adding style to ft...
# ....

# Here I want to remove one column to the ft (and only here, not when first creating the ft)
# something as:
# ft <- CreateCopyOfFlextable(ft,cols[-which(cols=='COLB')])
#
my_doc <- read_docx()
my_doc <- my_doc %>%  body_add_par("")   %>%
  body_add_flextable(value = ft) 

print(my_doc, target = 'c:/temp/doc.docx')
Billy answered 15/5, 2019 at 11:18 Comment(4)
Why don't you exclude the variable you don't need in col_keys?Orientalize
Sorry I don't understand. I can't exclude the COLB when creating the flextable() as I need this column to apply styles, this is why I need to remove it just before the body_add_flextableBilly
sorry. you style the column but then you don't want to display it?Orientalize
Here an example df <- data.frame(COLA=c('a','b','c'),COLB=c('','changevalue',''),COLC=c(10,12,13)) ft<-flextable(df) ft <- ft %>% style(i=which(ft$body$dataset$COLB=='changevalue'),pr_t=fp_text(color="black", font.size=11, bold=TRUE, italic=FALSE, underline=FALSE, font.family="Times New Roman"),part="body") ft<-compose(ft, i=2,j=3, value = as_paragraph(as_chunk('100')),part = 'body') # now I want to remove the COLB columns as I don't need it anymoreBilly
B
10

I just had the same problem and had a devil of a time Googling for a solution. @David-Gohel truly has the answer here, but I feel the need to provide a similar solution with additional explanation.

My problem and the OPs is that we wanted to use the data from columns that wouldn't be displayed to influence the formatting of columns that will be displayed. The concept that was not initially obvious is that you can send a data frame to flextable with more columns than you intend to display (instead of displaying all and deleting them you've used them). Then, by using the col_keys argument, you can select only those columns that you want to display while keeping the remaining ones around for additional processing (e.g., for using compose(), paragraph(), or add_chunk()).

If I understand correctly, COLB is supposed to be a flag to indicate that certain rows of COLC should be modified. If so, then my solution looks like this:

library(flextable)
library(magrittr)
library(officer)

df <- data.frame(COLA=c('a', 'b', 'c'),
                 COLB=c('', 'changevalue', ''),
                 COLC=c(10, 12, 13))

ft <- flextable(df, col_keys = c("COLA", "COLC")) %>% # Retain but don't display COLB
  compose(i = ~ COLB =='changevalue', # Use COLB for conditional modifications
          j = "COLC", 
          value = as_paragraph(as_chunk('100')), 
          part = 'body')  %>% 
  style(i = ~ COLB =='changevalue', # Use COLB for conditional formatting on COLC
        j = "COLC",
        pr_t = fp_text(color = "black", 
                       font.size = 11, 
                       bold = TRUE,
                       italic = FALSE,
                       underline = FALSE,
                       font.family = "Times New Roman"),
        part = "body")

ft

And here's what the above code produces (e.g., the "changevalue" column is the trigger for conditionally inserting 100 in COLC and also for changing the formatting):

Example Flextable

Bin answered 11/7, 2019 at 17:4 Comment(0)
O
4
library(flextable)
library(magrittr)
library(officer)

df <- data.frame(COLA=c('a','b','c'),
                 COLB=c('','changevalue',''),
                 COLC=c(10,12,13))
ft<-flextable(df, col_keys = c("COLA", "COLB"))
ft <- ft %>% 
  style(i= ~ COLB=='changevalue',
        pr_t=fp_text(color="black", font.size=11, bold=TRUE,  italic=FALSE, underline=FALSE, font.family="Times New Roman"),part="body")
ft<-compose(ft, i=2, j="COLB", value = as_paragraph(as_chunk('100')),part = 'body')
ft

Orientalize answered 15/5, 2019 at 12:49 Comment(5)
col_keys are the displayed variables, not a subsetOrientalize
Thanks David, but in your code, I'm loosing 10 and 13 valuesBilly
This is your code, not mine :) I have no idea what your are trying to achieve. Was just trying to help ;) ++Orientalize
Thanks for your help David, I understand. I have to rethink how to use flextable, I'm not sure your solution can be easaly integrated in my code (there are othe columns right to COLC, and other treatment. Thanks again for your help.Billy
Dear David, I have a related question about your flextable package HERE would you please take a look when find time?Fuchsia
O
3

Since version 0.9.4 of flextable, it is possible to delete columns and rows of a flextable:

library(flextable)

ft <- flextable(head(iris)) |> 
  delete_columns(1:3)
ft

enter image description here

Orientalize answered 23/10, 2023 at 11:32 Comment(0)
B
0

I'm styling another column based on COLB. Here an example:

df <- data.frame(COLA=c('a','b','c'),COLB=c('','changevalue',''),COLC=c(10,12,13))
ft<-flextable(df)
ft <- ft %>% style(i=which(ft$body$dataset$COLB=='changevalue'),pr_t=fp_text(color="black",   font.size=11, bold=TRUE,  italic=FALSE, underline=FALSE, font.family="Times New Roman"),part="body")
ft<-compose(ft, i=2,j=3, value = as_paragraph(as_chunk('100')),part = 'body')
# now I want to remove the COLB columns as I don't need it anymore
# ???????
my_doc <- read_docx()
my_doc <- my_doc %>%  body_add_par("")   %>%  body_add_flextable(value = ft) 

print(my_doc, target = 'c:/temp/orliange_p/sample.docx') %>% invisible()
Billy answered 15/5, 2019 at 12:45 Comment(1)
I already told you to not use x$body$dataset$..., this are internal structure and may change someday. Use only documented and exported functions.Orientalize

© 2022 - 2025 — McMap. All rights reserved.