Flextable Basic Conditional Formatting - r

I have a flextable that I am trying to conditionally format percentage numbers based if they are > or less than a certain %. It's a simple conditional format so I'm not sure why it's not working. I feel as though I'm missing something obvious here.
Here is an example:
myft = structure(list(Name = c("Bob", "Fred", "Joe"), `2020-03-30` = c(96,
100, 36)), row.names = c(NA, -3L), class = c("tbl_df", "tbl",
"data.frame"))
myft = flextable(myft)
myft = bg(myft, i = ~ Name > 50,
j = 2,
bg="red")
myft
This code produces this image:

You want to use the conditional formatting based on the "2020-03-30" column:
library(flextable)
myft = structure(list(Name = c("Bob", "Fred", "Joe"), `2020-03-30` = c(96,
100, 36)), row.names = c(NA, -3L), class = c("tbl_df", "tbl",
"data.frame"))
myft = flextable(myft)
myft = bg(myft, i = ~ `2020-03-30` > 50,
j = 2,
bg="red")
myft
Edit:
If you want conditional coloring across multiple columns, you could create a color matrix:
library(flextable)
myft = structure(list(Name = c("Bob", "Fred", "Joe"),
`2020-03-30` = c(96, 100, 36),
`2020-04-30` = c(30, 100, 36)),
row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
colormatrix <- ifelse(myft[, -1] > 50, "red", "white")
myft %>% flextable() %>% bg(j = 2:3, bg=colormatrix)

Related

how to identify whether all data frame in a list has unique ID or not

I have a list of dfs. I want to know whether there is a smart way to tell whether each df in lst has unique ID, and create a summary table like below"
Sample data:
lst<-list(structure(list(ID = c("Tom", "Jerry", "Mary"), Score = c(85,
85, 96)), row.names = c(NA, -3L), class = c("tbl_df", "tbl",
"data.frame")), structure(list(ID = c("Tom", "Jerry", "Mary",
"Jerry"), Score = c(75, 65, 88, 98)), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame")), structure(list(ID = c("Tom", "Jerry",
"Tom"), Score = c(97, 65, 96)), row.names = c(NA, -3L), class = c("tbl_df",
"tbl", "data.frame")))
We could loop over the list and check with n_distinct
library(dplyr)
library(stringr)
library(purrr)
map_dfr(setNames(lst, str_c("df", seq_along(lst))),
~.x %>%
summarise(UniqueID = c("N", "Y")[1 + (n_distinct(ID) == n())]), .id= 'Data')
-output
# A tibble: 3 × 2
Data UniqueID
<chr> <chr>
1 df1 Y
2 df2 N
3 df3 N
In base R:
data.frame(Data = paste0("df", seq(lst)),
UniqueID = ifelse(sapply(lst, \(x) length(unique(x$ID)) == nrow(x)), "Y", "N"))
Data UniqueID
1 df1 Y
2 df2 N
3 df3 N

how to get the variable list from each data frame in a list

I have a list of df, and I would like to rename the df as df1, df2, df3. and then create a summary like below to capture the variables in each df. What should I do?
I tried to use map to setNames for the data frames in lst, but I must do it in the wrong way. my current codes set variable names to df1, df2, def3. 😅
lst<- map( lst ~
setNames(.x, str_c("df", seq_along(lst))))
sample data:
lst<-list(structure(list(ID = c("Tom", "Jerry", "Mary"), Score = c(85,
85, 96), Test = c("Y", "N", "Y")), row.names = c(NA, -3L), class = c("tbl_df",
"tbl", "data.frame")), structure(list(ID = c("Tom", "Jerry",
"Mary", "Jerry"), Score = c(75, 65, 88, 98), try = c("Y", NA,
"N", NA)), row.names = c(NA, -4L), class = c("tbl_df", "tbl",
"data.frame")), structure(list(ID = c("Tom", "Jerry", "Tom"),
Score = c(97, 65, 96), weight = c("A", NA, "C")), row.names = c(NA,
-3L), class = c("tbl_df", "tbl", "data.frame")))
We get the column names with names/colnames by looping, paste to a single string with toString, convert to a data.frame column and bind the elements (_dfr).
library(purrr)
library(dplyr)
library(stringr)
setNames(lst, str_c("df", seq_along(lst))) %>%
map_dfr(~ tibble(Var = toString(names(.x))), .id = 'Data')
-output
# A tibble: 3 × 2
Data Var
<chr> <chr>
1 df1 ID, Score, Test
2 df2 ID, Score, try
3 df3 ID, Score, weight

How to create two stacked bar charts next to each other using ggplot. I want to recreate the below chart:

I have the below 2 dataframes:
lc2 <- structure(list(group = 1:3, sumpct = c(13, 32, 54)), class = "data.frame", row.names = c(NA,
-3L))
note this is for the "likelihood to click" bar (see image), where "extremely/somewhat likely" is
13%, neutral is 32, and extremely/somewhat unlikely is 54)
and
le2 <- structure(list(e = 1:3, t = c(13, 38, 48)), class = "data.frame", row.names = c(NA,
-3L))
note similarly this code above is for "likelihood to enroll" bar below.
But I want to create this:
lc2 <- structure(list(group = 1:3, sumpct = c(13, 32, 54)),
class = "data.frame", row.names = c(NA, -3L))
le2 <- structure(list(e = 1:3, t = c(13, 38, 48)),
class = "data.frame", row.names = c(NA, -3L))
lc2$type <- "click"
le2$type <- "enroll"
colnames(lc2) <- c("group", "pct", "type")
colnames(le2) <- c("group", "pct", "type")
library(data.table)
library(ggplot2)
dt <- rbindlist(list(lc2, le2))
dt[, group := as.factor(group)]
ggplot(dt, aes(x = type, y = pct, fill = group)) +
geom_bar(stat = "identity") +
geom_text(aes(label=scales::percent(pct/100)), position = position_stack(vjust = .5))+
theme_classic() +
coord_flip()

How make two row names in the Rshiny?

I have a dataset, which has a common feature - at the end of column names (after comma) is written the group to which a specific column corresponds to. Is it possible to create a table where two row column names will be used? In an example, the first row is Up and goes Quantity, Price, Quality. Is it also possible to somehow separate by empty column/ or some bold border these 3 groups (Up, Down and Total)? I know there is DT library that helps to make it easier, however, I am looking for the solution using shiny library only.
I also found that using tags$style() and CSS can help to solve it, however not familiar with CSS.
library(shiny)
df <- structure(list(Year = c(2022L, 2022L, 2022L, 2022L, 2022L),
Week = c(0, 1, 2, 3, 4),
`Quantity, Up` = c(335, 305, 740, 910, 515),
`Price, Up` = c(1, 2, 5, 5, 3),
`Quality, Up` = c(243, 243, 243, 12321.434052, 1706.327462),
`Quantity, Down` = c(-175, -900, -205, -35, 0),
`Price, Down` = c(243, 243, 1219.717851, 902.819827, 0),
`Quality, Down` = c(2834.205418, 243, -1219.717851, 902.819827, 0),
`Quantity, Total` = c(510, 1205, 945, 945, 515),
`Price, Total` = c(431, 32, 423, 342, 243),
`Quality, Total` = c(24, 4, -2, 42, 1706.327462)),
class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L),
groups = structure(list(Year = 2022L, .rows = structure(list(1:5), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))),
class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -1L), .drop = TRUE))
ui <- fluidPage(
# Application title
titlePanel("aFRR"),
# plot graphs
mainPanel(tabsetPanel(
tabPanel("Up",
h3(helpText("aFRR Price and Quantity")),
tableOutput("table_up"))
)
)
)
server <- function(input, output, session) {
output$table_up <- renderTable(df, na = "missing",align = 'c',striped = TRUE
)
}
shinyApp(ui, server)

Control number of rows when binding dataframes with different number of rows?

I have a dataframe generated by a function:
Each time it's of different number of rows:
structure(list(a = c(1, 2, 3), b = c("er", "gd", "ku"), c = c(43,
453, 12)), .Names = c("a", "b", "c"), row.names = c(NA, -3L), class = c("tbl_df",
"tbl", "data.frame"))
structure(list(a = c(1, 2), b = c("er", "gd"), c = c(43, 453)), .Names = c("a",
"b", "c"), row.names = c(NA, -2L), class = c("tbl_df", "tbl",
"data.frame"))
I want to be able like in a while loop to control the number of rows to be less then n (n = 4, 100, 4242...) when I bind rows.
Please advise how to do this using functional programming without a while loop?
I mean sometimes you will get n = 10 and the df before bind_rows is 7 and after binding the last one it will be 20. It's ok, I want the number of rows to be min_k (k >= n)
Here is my while loop doing this:
b <- list()
total_rows <- 0
while(total_rows < 1000) {
df <- f_produce_rand_df()
b[[length(b) + 1]] <- df
total_rows <- total_rows + nrow(df)
}

Resources