вызов пользовательской функции внутри al oop для создания пользовательских графиков в ggplot2 - PullRequest
2 голосов
/ 17 июня 2020

Вот пример набора данных, чтобы дать контекст моей проблеме:

df <- tibble(x1 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             x2 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             x3 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             )

head(df)

Я написал следующую функцию для создания нового фрагмента, который я хочу использовать в вызове ggplot2 :: ggplot ():


plot_data_prep <- function(dsn, pvar){

  pvar <- enquo(pvar)


  #convert the new plot_df and get it ready for plotting.
  plot_data <- dsn %>% 
    group_by(!!pvar) %>% count(.drop = F) %>% ungroup() %>% 
    mutate(pct = n/sum(n)*100,
         pct_lab = paste0(format(pct, digits = 1),'%'),
         pct_pos = pct + 0.6)

  return(plot_data)

}

plot_data_prep(df, x3)

Я могу использовать эту пользовательскую функцию при создании отдельных графиков:


ggplot(plot_data_prep(df,x3), mapping = aes(x=x3, y=pct))+
  geom_bar(stat = 'identity') +
  geom_text(aes(x = x3, y = pct_pos, label = pct_lab ))

, но когда я пытаюсь l oop через переменные 'x1', 'x2', и 'x3' в кадре данных, 'df', используя мою функцию plot_data_prep () для создания отдельных графиков для каждой переменной, я получаю сообщение об ошибке: 'Ошибка: столбец i неизвестен'


df_names <- names(df)

for (i in df_names){
    plot <- ggplot(plot_data_prep(df, i), mapping = aes_string(x=i, y='n')) +
      geom_bar(stat = 'identity') +
      geom_text(aes(x = i, y = pct_pos, label = pct_lab ))

  print(plot)
}

Я надеюсь, что кто-то сможет помочь мне понять, почему моя индексная переменная i для l oop не разрешает то, что мне нужно, чтобы мой код работал.

Спасибо.

1 Ответ

3 голосов
/ 17 июня 2020

Измените свою функцию, чтобы вместо этого принимала строковый ввод.

library(dplyr)
library(ggplot2)
library(rlang)

plot_data_prep <- function(dsn, pvar){

  #convert the new plot_df and get it ready for plotting.
  plot_data <- dsn %>% 
                 group_by(!!sym(pvar)) %>% count(.drop = F) %>% ungroup() %>% 
                 mutate(pct = n/sum(n)*100,
                        pct_lab = paste0(format(pct, digits = 1),'%'),
                        pct_pos = pct + 0.6)

   return(plot_data)

}

Подтвердите, что это работает:

plot_data_prep(df, 'x1')

Теперь вы можете oop поверх имен и сохранять графики в списке.

df_names <- names(df)
plot_list <- vector('list', length(df_names))

for (i in seq_along(df_names)) {
   plot <- ggplot(plot_data_prep(df, df_names[i]), 
                  mapping = aes(x= !!sym(df_names[i]), y=n)) +
           geom_bar(stat = 'identity') +
           geom_text(aes(x = !!sym(df_names[i]), y = pct_pos, label = pct_lab ))
  plot_list[[i]] <- plot
  print(plot)
}

Доступ к отдельным участкам можно получить, выполнив plot_list[[1]], plot_list[[2]] et c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...