I have a function which is creating table one by one for the list of banner. but now want to show them as binding as cbind.
I am able to bind the table by columns but not able to make banners as headers for table. also I want to remove names like n.x, n.y . just wanted to keep them N and i needed a flextable output
currently table is coming like below
library(knitr)
library(tidyverse)
library(flextable)
banner <- c("All","Other")
t1 <- structure(list(` ` = c("CA", "USA","UK", "GER", "Italy","France", "China"),
Local = c("38%", "58%","71%", "78%", "91%", "91%", "84%"),
Outsider = c("43%", "28%", "29%"," 9%", " 7%", " 4%", " 5%"),
Mixed = c("19%","13%", " 0%", "13%", " 1%", " 5%", "11%"),
N = c("9999", "9999","9999", "9999", "9999", "9999", "9999")), row.names = c(NA, -7L), class = "data.frame")
t2 <- structure(list(` ` = c("CA", "USA","UK", "GER", "Italy","France", "China"),
Local = c("71%", "93%","96%", "96%", "96%", "96%", NA),
Outsider = c(" 7%", " 4%", " 4%"," 0%", " 0%", " 0%", NA),
Mixed = c("21%"," 4%", " 0%", " 4%", " 4%", " 4%", NA),
N = c("2800", "2800","2800", "2800", "2800", "2800", NA)), row.names = c(NA, -7L), class = "data.frame")
tl <- list(t1,t2)
fun1 <- function(tl,banner){
t_list1<-list()
for (i in 1:length(banner))
{
t_list <- list()
t_list1[[i]] <- tl[[i]]
}
t1<-Reduce(function(...)merge(...,all=TRUE,by=" "),t_list1)
t1 <- t1 %>% flextable()
t1
}
fun1(tl=tl,banner = banner)
the output should be look llike below
One option to fix both your issues would be to first rename the column names of your sublists and add the banner
as a prefix. Additionally I convert your lists to dataframe at this step. After doing so you column names are unique and no .x
or .y
will be added when using merge
. And as a second benefit we can now utilize separate_header()
to split the column names to achieve your desired final result:
library(flextable)
tl <- list(t1, t2)
names(tl) <- banner
tl <- Map(
function(x, y) {
names(x)[-1] <- paste(y, names(x)[-1], sep = "_")
data.frame(x, check.names = FALSE)
},
tl, names(tl)
)
fun1 <- function(tl) {
t1 <- Reduce(function(...) merge(..., all = TRUE, by = " "), tl)
t1 |>
flextable() |>
separate_header()
}
fun1(tl = tl)
EDIT Of course could you move Map
inside your function to do the renaming.
library(flextable)
tl <- list(t1, t2)
fun1 <- function(tl, banner) {
tl <- Map(
function(x, y) {
names(x)[-1] <- paste(y, names(x)[-1], sep = "_")
data.frame(x, check.names = FALSE)
},
tl, banner
)
t1 <- Reduce(function(...) merge(..., all = TRUE, by = " "), tl)
t1 |>
flextable() |>
separate_header()
}
fun1(tl = tl, banner = banner)