Как сохранить графики по именам элементов в списке - PullRequest
0 голосов
/ 21 марта 2019

Я могу сохранить несколько графиков, но они именуют их в качестве первого значения в каждом элементе списка, а не в имени переменной.

delm2<-data.frame(N = c(5.881, 5.671, 7.628, 4.643, 6.598, 4.485, 4.465, 4.978, 4.698, 3.685, 4.915, 4.983, 3.288, 5.455, 5.411, 2.585, 4.321, 4.661), 
                  t1 = c("N", "N", "T", "T", "N", "N", "T", "N", "N", "N", "N", "T", "T", "T", "T", "T", "T", "N"), 
                  t3 = c("r","v", "r", "v", "v", "r", "c", "c", "v", "r", "c", "c", "r", "v","c", "r", "v", "c"), 
                  B = c(1.3, 1.3, 1.33, 1.25, 1.4, 1.34, 1.36, 1.39, 1.36, 1.42, 1.38, 1.31, 1.37, 1.44, 1.22, 1.4, 1.46, 1.35))


library(boot)

lapply(as.list(delm2[,c('N','B')]), 
       function(i){
         bmp(filename = paste0(i,".bmp"), width = 350, height = 400)
         glm.diag.plots(glm(i ~ t1*t3,data=del))
         dev.off()   
       })

Это сохраняет графики, но они именуются числовыми значениямииз данных, а не из имени каждой цели lapply ... , т.е. текущий вывод - это два файла с именами "5.881" и "1.3", когда мне нужны те же два файла, но с именами "N" и "B""

Я думал, что смогу изменить paste0(i,".bmp") на paste0(names(i),".bmp"), но это просто сохранит первый, без имени.

Похоже, вы можете дать имена, которыеэто просто целые числа в Как сохранить и назвать несколько графиков с помощью R , но я хочу, чтобы имена переменных из списка или двух чисел N и B в delm2.

Это выглядит из Сохранение списка графиков по их именам () , как это было бы проще с выводом ggplot, но ggsave не работал на одном glm.diag.plots выводе.

1 Ответ

1 голос
/ 22 марта 2019

(Не обращайте внимания на мое предыдущее предложение, используя Map.)

Большой вывод - как вывести формулу динамически. Один способ - с as.formula, который берет строку и преобразует ее в формулу, которую можно использовать в функции генерации модели (например).

Одна проблема с использованием lapply(as.list(delm2[,c('N','B')]), ...) заключается в том, что остальные данные (то есть столбцы t1 и t3) не передаются, только один вектор за один раз. (Мне интересно, является ли ваша ссылка на del опечаткой, неопубликованными / скрытыми данными или чем-то еще.)

Попробуйте это:

lapply(c("N", "B"), function(nm) {
  bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
  glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
  dev.off()
})

В общем, я не люблю нарушать область видимости внутри этих функций. То есть я стараюсь не выходить за пределы lapply для данных, когда я могу достаточно легко их передать. Вышеизложенное в педантично-языковой манере может выглядеть так:

lapply(c("N", "B"), function(nm, x) {
  bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
  glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
  dev.off()
}, x = delm2)

Хотя это сохраняет сферу, это может сбить с толку, если вы не понимаете, что происходит.

Это может быть прекрасное время для использования for вместо одной из *apply* функций. Все, что вы хотите, находится в побочном эффекте, и, поскольку for и *apply являются фактически одинаковой скоростью, вы получаете удобочитаемость:

for (nm in c("N", "B")) {
  bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
  glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = delm2))
  dev.off()
}

(В данном случае «нарушение области видимости» отсутствует, поэтому я использовал исходную переменную.)


В скобках , чтобы связать мой отредактированный и неправильный ответ, включающий Map. Вот пример использования Map, который делает больше для демонстрации того, что делают Mapmapply), что на самом деле улучшает ваши непосредственные потребности.

Если по какой-то причине вы хотели, чтобы они назвали что-то отличное от "N.bmp", вы можете сделать это:

Map(function(fn, vn, x) {
  bmp(filename = paste(nm, ".bmp"), width = 350, height = 400)
  glm.diag.plots(glm(as.formula(paste(nm, "~ t1*t3")), data = x))
  dev.off()
}, c("N2.bmp", "b3456.bmp"), c("N", "B"), list(delm2))

Из этого следует отметить две вещи:

  • Использование list(delm2) состоит в том, чтобы обернуть эту структуру в одну «вещь», которая передается повторяемой в отображенную функцию. Если бы мы просто сделали delm2 (без list(...)), то он попытался бы использовать первый столбец delm2 с каждым из первых элементов. Это может быть полезно в других сценариях, но в вашем примере glm вам нужны другие столбцы, поэтому вы не можете включать только один столбец за раз. (Ну, есть способы сделать это тоже ... но сейчас это важно.)
  • При первом вызове анонимной функции fn равно "N2.bmp", vn is "N" , and x is the full dataset of delm2 . The second time the anon-func is called, fn is "b3456.bmp" , уп is "B" , and х is again the full dataset of delm2`.

Я помечаю эту часть как "в скобках", потому что она на самом деле не добавляет к этой проблемы, но так как я начал этот путь в своем первом ответе, я решил продолжить с методологией, «почему» моего выбора Map. В конце концов, я думаю, что решение for или одно из решений lapply должно подойти вам.

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