Skip to content

Instantly share code, notes, and snippets.

@paullemmens
Last active April 12, 2019 13:30
Show Gist options
  • Save paullemmens/e518d997160927459cb847c87eeb1bf2 to your computer and use it in GitHub Desktop.
Save paullemmens/e518d997160927459cb847c87eeb1bf2 to your computer and use it in GitHub Desktop.
rlang, tidyeval, dplyr, ggplot and non-syntactic column names
## I have a data set something like this.
mtc <- mtcars %>%
mutate(cyl = factor(cyl),
gear = factor(gear),
`Q17_anx/worry about abc` = gear,
`Q17_anx about abc` = gear)
## An admittedly ugly function (on various levels / from diverse perspectives)
## in which I'm trying baby steps for tidy evaluation.
ppp <- function(dfr, q, by = NULL, n.resp = length(unique(dfr$cyl))) {
grp <- rlang::syms(q)
response <- rlang::ensym(q)
## count answered and skipped.
skipped <- dfr %>% filter(is.na(!!!grp)) %>% count(!!!grp) %>% pull(n)
N <- n.resp - skipped
if (!is.null(by)) {
grp <- rlang::syms(list(q, by))
}
d <- dfr %>%
filter(!is.na(!!response)) %>%
count(!!!grp)
if (!is.null(by)) {
b <- rlang::ensym(by)
d <- d %>%
group_by(!!b) %>%
mutate(N = sum(n))
} else {
d <- d %>% mutate(N = sum(n))
}
d <- d %>%
mutate(perc = n/N)
N <- sum(d$n)
p <- d %>%
ggplot(mapping = aes(x = !!response, y = perc, colour = !!response, fill = !!response)) +
geom_col() +
labs(x = '', y = '') +
scale_y_continuous(limits = range(0, 1), breaks = seq(0, 1, 0.10), labels = scales::percent) +
scale_x_discrete(limits = rev(levels(d[[q]]))) +
coord_flip() +
guides(fill = FALSE, colour = FALSE) +
theme_bw() +
theme(strip.background = ggplot2::element_rect(colour = NA, fill = NA))
if (!is.null(by)) p <- p + facet_wrap(as.formula(paste('~', by)))
return(p)
}
## Then I'm calling the function like this.
mtc %>% ppp(q = 'cyl', by = 'gear') # Works
mtc %>% ppp(q = 'cyl', by = 'Q17_anx/worry about abc') # ERROR (unexpected symbol)
mtc %>% ppp(q = 'cyl', by = 'Q17_anx about abc') # ERROR ibid
## Error for the last above call:
## Error in parse(text = x, keep.source = FALSE) :
## <text>:1:11: unexpected symbol
##1: ~ Q17_anx about
## ^
@paullemmens
Copy link
Author

On twitter @_lionelhenry said

You need facet_wrap(vars(!!by)).

If your function is meant to take strings, I wouldn't use NSE in its interface at all. Just use sym() and syms() to transform to symbols. Or pass the raw strings directly to .data[[, that's a bit safer:

facet_wrap(vars(.data[[by]]))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment