1

I wrote a quick function to plot some demographics, but it isn't recognizing the variable I chose. I know that poverty_rate is a column in my data frame, it shows up when I do names(df) and I've used it in prior chunks. Yep when I run the function below, I get Error in mean(demog, na.rm = TRUE) : object 'poverty_rate' not found. What am I doing wrong?

dense_plot_demos <- function(df, id_list, demog, color_id, demo_name, qual) {
  df %>%
  filter(GEOID %in% id_list) %>%
  group_by(GEOID) %>%
  mutate(avg_var = mean(demog, na.rm=TRUE)) %>%
  ggplot(aes(x=avg_var)) + 
  geom_histogram(aes(y=..density..), color="black", fill="white", bins=20) + 
  geom_density(alpha=.5, fill=color_id) + 
  theme_bw() + 
  xlab(demo_name) + 
  ylab("Density") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  labs(title = paste(demo_name, "in", qual, "Filing Counties"))
}
top_pov <- dense_plot_demos(df, top_ids, poverty_rate, color_pal[1], "Poverty Rate", "Highest")

ETA: Thank you all of your suggestions and resources. I found that the following worked with minimal modification to my function:

dense_plot_demos <- function(df, id_list, demog, color_id, demo_name, qual) {
  demog <- sym(demog)
  df %>%
  filter(GEOID %in% id_list) %>%
  group_by(GEOID) %>%
  mutate(avg = (mean(!! demog, na.rm=TRUE))) %>%
  ggplot(aes(x=avg)) + 
  geom_histogram(aes(y=..density..), color="black", fill="white", bins=20) + 
  geom_density(alpha=.5, fill=color_id) + 
  theme_bw() + 
  xlab(demo_name) + 
  ylab("Density") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  labs(title = paste(demo_name, "in", qual, "Filing Counties"))
}

top_pov <- dense_plot_demos(ecplot, top_lists, "poverty_rate", color_pal[1], "Poverty Rate", "Highest")
carousallie
  • 776
  • 1
  • 7
  • 25
  • Have you try to feed your function with `"poverty_rate"` instead of `poverty_rate` ? – dc37 Nov 21 '19 at 19:42
  • You should provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – M-- Nov 21 '19 at 19:43
  • @dc37 I tried "poverty_rate" but it said `argument is not numeric or logical: returning NA`. – carousallie Nov 21 '19 at 19:45
  • 1
    This is an issue of passing dynamic column names to functions in the tidyverse. Some info [here](https://stackoverflow.com/questions/26003574/use-dynamic-variable-names-in-dplyr), [here](https://stackoverflow.com/questions/53148816/dplyr-summarise-with-dynamic-columns), and [here](https://stackoverflow.com/questions/29678435/how-to-pass-dynamic-column-names-in-dplyr-into-custom-function). – ravic_ Nov 21 '19 at 20:10

1 Answers1

1

Hi carousallie the suggestions by @camille,@ravic_ will work for your problem. The main point is to evaluate mean(demog, na.rm=TRUE) correctly. For the code you have written, you can have a quick fix by creating a dummy column called demog, which is a replicate of your demog variable:

dense_plot_demos <- function(df, id_list, demog, color_id, demo_name, qual) {

  #add this line
  df$demog <- df[,demog]
  df %>%
  filter(GEOID %in% id_list) %>%
  group_by(GEOID) %>%
  mutate(avg_var = mean(demog, na.rm=TRUE)) %>%
  ggplot(aes(x=avg_var)) + 
  geom_histogram(aes(y=..density..), color="black", fill="white", bins=20) + 
  geom_density(alpha=.5, fill=color_id) + 
  theme_bw() + 
  xlab(demo_name) + 
  ylab("Density") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  labs(title = paste(demo_name, "in", qual, "Filing Counties"))
}

#simulate data
set.seed(100)
df <- data.frame(
GEOID = sample(letters,300,replace=TRUE),
poverty_rate = rnorm(300)
)
# some values for your other input
top_ids = letters[1:10]
color_pal = "lightblue"
# plot, this works
# note use "poverty_rate" as demog
top_pov <- dense_plot_demos(df, top_ids, 
"poverty_rate", color_pal[1], "Poverty Rate", "Highest")

The above works because you don't have a column called "demog" in your dataframe(I hope), so your subsequent code functions like normal.

If you want to really get it to work without a dummy, then change the mutate part to:

mutate(avg_var=eval(parse(text=paste("mean(",demog,",na.rm=TRUE)"))))

most likely does not look like your plot lol

StupidWolf
  • 45,075
  • 17
  • 40
  • 72
  • actually, using ```mutate(avg_var=mean(demog, na.rm = T))``` instead of ```mutate(avg_var=eval(parse(text=paste("mean(",demog,",na.rm=TRUE)"))))``` works for me – bretauv Nov 21 '19 at 20:51
  • yes you are right, @bretauv i got the 2 versions of the code confused. Thanks you for the eagle eyes :) getting dark here – StupidWolf Nov 21 '19 at 20:52