использование mapply с ggplot

#r #ggplot2

#r #ggplot2

Вопрос:

Продолжаю свои поиски работы с функциями и ggplot:

Я разобрал основные способы использования lapply и ggplot для циклического просмотра списка y_columns для создания отдельных графиков:

 require(ggplot2)
# using lapply with ggplot

df <- data.frame(x=c("a", "b", "c"), col1=c(1, 2, 3), col2=c(3, 2, 1), col3=c(4, 2, 3))
cols <- colnames(df[2:4])
myplots <- vector('list', 3)

plot_function <- function(y_column, data) { 
     ggplot(data, aes_string(x="x", y=y_column, fill = "x"))  
     geom_col()   
     labs(title=paste("lapply:", y_column))
}

myplots <- lapply(cols, plot_function, df)
myplots[[3]])
 

lapply_plot_3

Я знаю, что ввести во вторую переменную, которую я буду использовать для выбора строк. В моем минимальном примере я пропускаю выделение и просто повторно использую те же графики и dfs, что и раньше, я просто добавляю 3 итерации. Поэтому я хотел бы сгенерировать те же три графика, что и выше, но теперь помеченные как итерации A, B и C.

Мне потребовалось некоторое время, чтобы разобраться в синтаксисе, но теперь я понимаю, что mapply нуждается в векторах одинаковой длины, которые передаются функции в виде совпадающих пар. Итак, я использую expand.grid для генерации всех пар переменных 1 и 2 для создания фрейма данных , а затем передаю первый и второй столбцы через mapply . Следующая проблема , с которой нужно было разобраться , заключалась в том , что мне нужно передать фрейм данных в виде списка MoreArgs = . Так что, похоже, все должно быть хорошо. Я использую тот же синтаксис aes_string() , что и выше, в моем lapply примере.

Однако по какой-то причине сейчас он не оценивает y_column должным образом, а просто принимает его как значение для построения графика, а не как индикатор для отображения содержащихся в нем значений df$col1 .

ПОМОГИТЕ!

 require(ggplot2)
# using mapply with ggplot

df <- data.frame(x=c("a", "b", "c"), col1=c(1, 2, 3), col2=c(3, 2, 1), col3=c(4, 2, 3))
cols <- colnames(df[2:4])
iteration <- c("Iteration A", "Iteration B", "Iteration C")

multi_plot_function <- function(y_column, iteration, data) { 
     plot <- ggplot(data, aes_string(x="x", y=y_column, fill = "x"))  
     geom_col()   
     labs(title=paste("mapply:", y_column, "___", iteration))
}

# mapply call 
combo <- expand.grid(cols=cols, iteration=iteration)
myplots <- mapply(multi_plot_function, combo[[1]], combo[[2]], MoreArgs = list(df), SIMPLIFY = F) 
myplots[[3]]
 

mapply_plot_3

Комментарии:

1. Что вы имеете в виду? В ваших руках код выдает другой график для версии mapply, чем у меня? Или это то же самое, что и с моей функцией lapply (т. Е. Отображение значений 4, 2, 3 для a, b, c соответственно)?

2. Извините, я просто смотрел на проблему с кодом ранее

Ответ №1:

Возможно, здесь нам придется использовать rowwise

 out <- lapply(asplit(combo, 1), function(x)
           multi_plot_function(x[1], x[2], df))
 

В коде операционной системы единственная проблема заключается в том, что столбцы предназначены factor для ‘combo’, поэтому они неправильно анализируются. Если мы изменим его на character , это сработает

 out2 <- mapply(multi_plot_function, as.character(combo[[1]]), 
    as.character(combo[[2]]), MoreArgs = list(df), SIMPLIFY = FALSE) 
 

-тестирование

 out2[[1]]
 

введите описание изображения здесь

Комментарии:

1. Потрясающе. Спасибо за оба решения. Приятно узнать об этой asplit опции (которая кажется более простой, чем использование mapply), а также спасибо за обнаружение ошибки. Непонимание точной природы передаваемого на данный момент является моей проблемой кодирования номер один.

2. @MarioNiepel Я думаю, что это основано на expand.grid том, что по какой-то причине по умолчанию возвращается stringsAsFactors как TRUE

3. Да, это так часто моя проблема. Здесь я не уловил этого, потому что, когда я проверил эту проблему, я просто напечатал значения, которые не говорят мне, правильный ли это тип. Я все больше и больше осознаю это, но это процесс обучения. Точно так же, как потребовалось время из моей жизни, чтобы понять, что сначала я должен был обернуть df в список. : D

4. @MarioNiepel Обычно я делаю str это сначала, прежде чем что-либо делать, потому что это может дать жизненно важные признаки

5. Да, это имеет большой смысл. Мне нужно усвоить, что «видеть значение» менее важно, чем понимание типа / класса.