How do I pass a variable to "count()" inside a function? - r

There's a block of code that I'm using over and over in a project. It works fine when I run it straight:
kable(
starwars %>%
count(gender),
col.names = c("Response", "Count")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
But I want to create a function that I can just call once to run it. I expected that this would work:
fancy_table <- function(x,y) {
kable(
y %>%
count(x),
col.names = c("Response", "Count")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
}
But when I try to run it with fancy_table(gender, starwars), I get an error:
Error: Column `x` is unknown
How do I pass a function variable to count()?

Related

Kables isn't seeing my kable_styling attributes?

I'm trying to spit out two tables side by side, using knitr::kables.
I can't figure out how to make my styles stick, though. If I run one kable, the styles work fine:
kable(
caption = "Oh look! A Caption",
starwars %>%
count(gender, sex) %>%
arrange(desc(gender))
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
gives me a tidy looking table:
But if I try to set two up side by side, the formatting (or kable_styling) gets lost:
knitr::kables(list(
kable(caption = "Oh look! A Caption",
starwars %>%
count(gender, sex) %>%
arrange(desc(gender))) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")),
kable(caption = "Oh look! A Caption",
starwars %>%
count(gender, sex) %>%
arrange(desc(gender))) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
))
The formatting all just evaporates:
How do I get kable_styling to apply to two kables?
The extremely unsatisfying solution turned out to be adding a third kable_styling() call:
knitr::kables(list(
kable(caption = "Species",
starwars %>%
count(species) %>%
filter(n > 1)
) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed")),
kable(caption = "Homeworld",
starwars %>%
count(homeworld) %>%
filter(n > 1)
) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
)
) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
That seems verbose, but it works.

how to specify dynamically last row number in row_spec kable()?

I am generating different tables of different row length, so I want to have all the text of certain color, but I have a question about the last row of my code in row_spec
library(kable)
library(kableExtra)
mtcars %>% filter(cyl=4) %>%
kable(align=c("l", rep("c", ncol(.)-1)),bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
kable_styling(c("striped", "hover", "condensed", "responsive"), full_width = TRUE) %>%
row_spec(0: nrow(.), color = "black")
0: nrow(.) is not valid and I am not sure why, while rep("c", ncol(.)-1)) works.
I think it doesn't work because nrow(.) returns NULL:
library(kable)
library(kableExtra)
mtcars %>%
kable(align=c("l", rep("c", ncol(.)-1)),bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
kable_styling(c("striped", "hover", "condensed", "responsive"), full_width = TRUE) %>% nrow(.)
#NULL
You could do this to color all rows:
mtcars %>%
kable(align=c("l", rep("c", ncol(.)-1)),bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
kable_styling(c("striped", "hover", "condensed", "responsive"), full_width = TRUE) %>%
row_spec(1:nrow(mtcars),color = "black")
Even though not elegant, I would do it in two steps:
library(knitr)
library(kableExtra)
library(dplyr)
# Step 1: Prepare data
temp <- mtcars %>%
filter(cyl == 4) %>%
sample_n(sample(2:nrow(.), 1)) %>%
select(1:3)
# Step 2: Produce table
temp %>%
kable(align=c("l", rep("c", ncol(temp)-1))) %>%
kable_styling(c("striped", "hover", "condensed"), full_width = FALSE) %>%
# Format last row:
row_spec(nrow(temp), color = "red", italic = TRUE, bold = TRUE)

how to combine R ifelse() and kable()

I have R Markdown scripts I run periodically which contain conditional tables with what I'll call violators. Here's an example data frame:
df <- data.frame(Person = c("Jack", "Jill"), Violator = c("F", "F"))
#> Person Violator
#> 1 Jack F
#> 2 Jill F
I only want to show violators (Violator == "T") and there aren't any this month. So my 'normal' kable code below gives me this error, "subscript out of bounds" which I'd expect.
How can I modify my kable code to 'do nothing' if violator does not equal "T". Is ifelse() the way to go? I'm open to kableExtra() solutions.
kable(df %>% filter(Violator == "T"), "html", align = "l") %>%
kable_styling("striped", "hover", full_width = F) %>%
column_spec(1, bold = T, background = "#FFFFFF") %>%
collapse_rows(columns = 1)
This simple approach should work, I think:
```{r}
temp <- df %>% filter(Violator == "T")
if(nrow(temp) != 0){
kable(temp, "html", align = "l") %>%
kable_styling("striped", "hover", full_width = F) %>%
column_spec(1, bold = T, background = "#FFFFFF") %>%
collapse_rows(columns = 1)
}
```

R Notebook: place knitr::kable tables side-by-side?

I'm writing up some figures and tables in an R Notebook, and I have a few tables I would like to place side-by-side. I am knitting the notebook to a html. The code I have at the moment (below) works, but both tables are aligned to the left. What I would really like is for them to appear side-by-side but also be centered. Any suggestions please? dt_tot and dt_tot_week are data.tables.
knitr::kable(dt_tot, "html", caption = caption) %>%
kableExtra::kable_styling(bootstrap_options = c("hover"),
full_width = FALSE, position = "float_left")
knitr::kable(dt_tot_week, "html", caption = caption) %>%
kableExtra::kable_styling(bootstrap_options = c("hover"),
full_width = FALSE, position = "float_left")
If you're knitting to HTML, you should be able to use knitr::kables. This gives me two tables, side by side:
library(tidyverse)
library(kableExtra)
knitr::kables(list(
kable(caption = "Left Table",
starwars %>%
count(species) %>%
filter(n > 1)
) %>% kable_styling(),
kable(caption = "Right Table",
starwars %>%
count(homeworld) %>%
filter(n > 1)
) %>% kable_styling()
)
) %>% kable_styling()
You just need to change the position of table formed by dt_tot_week to float_right instead of float_left. I' am sure that must have been a typo in your code.
knitr::kable(dt_tot, "html", caption ="left Tbl") %>%
kableExtra::kable_styling(bootstrap_options = c("hover"),
full_width = FALSE, position = "float_left")
knitr::kable(dt_tot_week, "html", caption ="right Tbl") %>%
kableExtra::kable_styling(bootstrap_options = c("hover"),
full_width = FALSE, position = "float_right")

R- knitr:kable - How to display table without column names?

Currently, I have this data frame (PS):
My code to display this table is:
kable(PS) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
I want to display the table without column names like this:
Problem is
1) The column names should be non-empty, and attempts to use empty names will have unsupported results
2) If I convert the data frame and remove the column names and then use kable like this:
PS.mat <- as.matrix(PS)
colnames(PS.mat) <- NULL
kable(PS) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
I get the following error
Error in kable_info$colnames[[length(kable_info$colnames)]] : attempt to select less than one element in integerOneIndex
I also tried the following parameter but with no results
kable(PS, col.names = NA)
EDIT 1:
A reproducible example:
if (!require(pacman)) install.packages("pacman")
p_load("lubridate","knitr","kableExtra","scales")
Statistics <- c("AUM",
"Minimum Managed Account Size",
"Liquidity",
"Average Margin / Equity",
"Roundturns / $ Million / Year",
"Incentive Fees",
"Instruments Traded")
Value <- c("$30K","$30K","Daily","50%","6,933","25%","ES")
AI <- data.frame(Statistics,Value);
kable(AI) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
Depending on your desired output format you could make use of such functions. For pandoc:
x = kable(AI, format="pandoc") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
cat(x[3:9], sep="\n")
For html:
x = kable(AI, format="html") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
gsub("<thead>.*</thead>", "", x)

Resources