Daniel
Daniel

Reputation: 435

Extract value from tibble in R markdown inline code

I'm looking to access a value from a tibble using inline code in an R Markdown document.

The following code gives me a 1 x 2 tibble.

#library(tidyverse)
#library(knitr)

# Minimal working example
df <- tibble(
  Event = c("Swimming","Swimming","Swimming","Camping","Hiking","Hiking")
)
df

# Creates 1 row x 2 column
df %>% count(Event) %>% slice(which.max(n))

If I create an object in a code chunk, I can select [1,1] and report that inline:

temp <- df %>% count(Event) %>% slice(which.max(n))

# The most popular event was `r temp[1,1]`.

# which becomes "The most popular event was Swimming."

Is there a way to do that within my dplyr pipes without creating a new object? Ideally, I would be able to do it all via inline code, something like:

`r df %>% count(Event) %>% slice(which.max(n)) %>% df[1,1]`  # fails

Stepping back, I'm looking for a generalizable technique to use to select particular rows and cells from within a series of dplyr commands without creating new objects along the way.

Upvotes: 2

Views: 6136

Answers (3)

Daniel
Daniel

Reputation: 435

I'm learning several ways to do this - thanks all!

1. Following @labatnok:

r df %>% count(Event) %>% slice(which.max(n)) %>% {.[1,1]}

2. Following @mmyoung77:

`r df %>% count(Event) %>% arrange(desc(n)) %>% slice(1) %$% Event`

# result
[1] "Swimming"

This approach avoids using "which.max." The "1" in slice(1) indicates the row, then %$% Event indicates the column (by name).

It's not quite as easy to follow what is happening as base R's [1,1], but it gets the job done.

3. Following @Mo Alfaifi:

(df %>% count(Event) %>% arrange(desc(n)))[1,1]

This approach makes it easier to tell which row/column you are selecting. It also avoids needing to name the column.

4. Following @Colum You:

df %>% count(Event) %>% slice(which.max(n)) %>% magrittr::extract2("Event")

Upvotes: 1

Moh
Moh

Reputation: 188

Is this what you are after?

df %>% count(Event)

# A tibble: 3 x 2
#  Event        n
# 1 Camping      1
# 2 Hiking       2
# 3 Swimming     3

# To get the first row
(df %>% count(Event))[1,]

# Event       n
# 1 Camping   1

Upvotes: 0

Calum You
Calum You

Reputation: 15062

Your line of code that you want to display inline doesn't run even when not in R Markdown, try it in the console. When using special operators like [, [[, $ with the pipe, you need to specify them in the prefix rather than infix form like other functions, like this. Note the comparison of your attempted code, and alternatively using [[ to drill down and select just the text instead of returning a tibble.

library(tidyverse)
df <- tibble(
  Event = c("Swimming","Swimming","Swimming","Camping","Hiking","Hiking")
)

df %>% count(Event) %>% slice(which.max(n)) %>% `[`(1,1)
#> # A tibble: 1 x 1
#>   Event   
#>   <chr>   
#> 1 Swimming
df %>% count(Event) %>% slice(which.max(n)) %>% `[[`("Event")
#> [1] "Swimming"

However, this doesn't quite solve your problem because R Markdown uses backticks to denote the inline code, and it's complicated to change the parsing rules that knitr uses to find and evaluate inline code, so here it would think the code ended at `[`. So you can instead use the magrittr aliases for these functions, extract and extract2 in inline code:

Most popular event was `r df %>% count(Event) %>% slice(which.max(n)) %>% magrittr::extract2("Event")`

which correctly prints Most popular event was Swimming in the rendered markdown.

Upvotes: 2

Related Questions