Reputation: 5828
I'm trying to conditionally reorder columns but only when when specified by a function parameter. I see other examples that show how to add conditionals inside dplyr statements,(like this) but it isn't working for me.
I've got a dataset with two columns that looks like this:
Role
1 Primary
2 Secondary
3 Primary
4 Primary
Zap
1 Enabled
2 Disabled
3 Enabled
4 Enabled
And my code looks like this:
my_bar_chart <- function(data, column, title, change_order=FALSE){
toReturn <- data %>%
group_by({{column}}) %>%
summarize(count = n()) %>%
mutate(percent = count/sum(count)) %>%
mutate(column = reorder({{column}}, -count, FUN=identity)) %>%
ggplot(aes(x=column, y=count)) +
xlab(title)+
geom_col(fill='#cccccc') +
geom_text(aes(label = paste0(round(100 * percent, 1), "%")))
return(toReturn)
}
p1 <- my_bar_chart(mydata, Role, "EA5 Controller Role", TRUE)
p2 <- my_bar_chart(mydata, Zap, "Another title", FALSE)
And that works ok, but now when I try to get working is the second mutate statement, to conditionally reorder when I pass in TRUE into the function change_order param. Here is the conditional mutate that isn't working:
mutate(column = case_when(
change_order == TRUE ~ reorder({{column}}, -count, FUN=identity),
change_order == FALSE ~ column)) %>%
It is giving me this error:
Error in eval_tidy(pair$rhs, env = default_env) : object 'Role' not found
Any ideas what I'm doing wrong?
Upvotes: 1
Views: 131
Reputation: 886938
The second condition is returning column
and not inside the {{}}
, along with the type
of object that should be the same
my_bar_chart <- function(data, column, title, change_order=FALSE){
data %>%
group_by({{column}}) %>%
summarize(count = n()) %>%
mutate(percent = count/sum(count),
!! rlang::enquo(column) := case_when(change_order ~
reorder({{column}}, -count, FUN=identity), TRUE ~ factor({{column}})) ) %>%
ggplot(aes(x={{column}}, y=count)) +
xlab(title)+
geom_col(fill='#cccccc') +
geom_text(aes(label = paste0(round(100 * percent, 1), "%")))
}
-testing
my_bar_chart(mydata, Role, "EA5 Controller Role", TRUE)
Note that the reorder
is creating some attributes to the concerned column which would be dropped within the case_when
as it expects both the expressions to have the same structure output. Instead, we can use if/else
here
my_bar_chart <- function(data, column, title, change_order=FALSE){
out <- data %>%
group_by({{column}}) %>%
summarize(count = n()) %>%
mutate(percent = count/sum(count),
!! rlang::enquo(column) := if(change_order)
reorder({{column}}, -count, FUN=identity) else {{column}} )
print(str(out))
ggplot(out, aes(x={{column}}, y=count)) +
xlab(title)+
geom_col(fill='#cccccc') +
geom_text(aes(label = paste0(round(100 * percent, 1), "%")))
}
-testing
Check the print
output of the structure of dataset
my_bar_chart(mydata, Role, "EA5 Controller Role", TRUE)
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 3 variables:
# $ Role : Factor w/ 2 levels "Primary","Secondary": 1 2
# ..- attr(*, "scores")= int [1:2(1d)] -3 -1
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "Primary" "Secondary"
# $ count : int 3 1
# $ percent: num 0.75 0.25
NULL
my_bar_chart(mydata, Role, "EA5 Controller Role", FALSE)
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 3 variables:
# $ Role : chr "Primary" "Secondary"
# $ count : int 3 1
# $ percent: num 0.75 0.25
Upvotes: 1