R — назначение графика списку с переменными именами

Я пытаюсь присвоить график списку, названному через переменную (snm). Мой фрагмент кода — это все варианты, которые я пытался сделать, чтобы заставить его работать. Какой еще вариант мне не хватает? Спасибо.

Моя цель состоит в том, чтобы перебрать мои назначения графика, используя оператор IF, чтобы изменить snm и несколько других переменных, которые я буду использовать в графиках.

for (x in seq(0,1)) {
  if (x==0) {
    snm="grad"
  } 
  else if (x==1) {
    snm="start"
  }

    assign(snm,list(),envir=.GlobalEnv) #works
    assign(snm[[1]],ggplot(data=TDSF, aes(x=Graduation))+geom_histogram()+labs(title="A"),envir=.GlobalEnv) #works
    assign(snm[[2]],ggplot(data=TDSF, aes(x=Graduation,weights=Donation))+geom_bar()+labs(title="B"),envir=.GlobalEnv) #fails "subscript out of bonds"
    assign(snm[[3]],ggplot(data=TDSF, aes(x=State,weights=Donation))+geom_bar()+labs(title="B")+scale_y_sqrt(),envir=.GlobalEnv) #fails "subscript out of bonds"
    grid.arrange(grad[[1]],grad[[2]],grad[[3]])
}

Частичное решение, основанное на @MrFlick и @hrbrmstr, но 1) я должен использовать do.call в цикле, иначе я получаю те же графики и 2) видя mapply, я чувствую, что должен иметь возможность его использовать, но не могу заставить его Работа.

library(ggplot2)
library(gridExtra)

set.seed(1492)
TDSF <- data.frame(Graduation=sample(1950:2010, 30),
                   Donation=sample(300:10000, 30),
                   Start.Year=sample(1950:2010,30),
                   State=sample(state.abb,30,replace=TRUE))

plots <- list()
for (x in seq(0,1)) {
  if (x==0) {
    nm=quote(Graduation)
    snm="grad"
  } 
  else if (x==1) {
    nm=quote(Start.Year)
    snm="start"
  }
  plots[[snm]]<-list()
  plots[[snm]][[1]] <- ggplot(data=TDSF, aes(x=eval(nm)))+geom_histogram()+labs(title=paste("Number of People per",snm,"Year"))
  plots[[snm]][[2]] <- ggplot(data=TDSF, aes(x=eval(nm),weights=Donation))+geom_bar()+labs(title=paste("Donations by",snm,"Year"))
  plots[[snm]][[3]] <- ggplot(data=TDSF, aes(x=State,weights=Donation))+geom_bar()+labs(title="Donations by State")+scale_y_sqrt()
}

do.call(grid.arrange,plots[["grad"]])
do.call(grid.arrange,plots[["start"]])

попытка сопоставления:

plot<-mapply(function(snm,nm) list(
  {ggplot(data=TDSF, aes(x=nm))+geom_histogram()+labs(title=paste("Number of People per",snm,"Year"))},
  {ggplot(data=TDSF, aes(x=nm,weights=Donation))+geom_bar()+labs(title=paste("Donations by",snm,"Year"))},
  {ggplot(data=TDSF, aes(x=State,weights=Donation))+geom_bar()+labs(title="Donations by State")+scale_y_sqrt()}
), c("grad","start"),c("Graduation","Start.Year"),SIMPLIFY = FALSE)

do.call(grid.arrange,plot[["grad"]])
do.call(grid.arrange,plot[["start"]])

person atclaus    schedule 20.08.2016    source источник
comment
Хороший код R не использует assign(). Я предлагаю вам избавиться от этой привычки как можно скорее.   -  person MrFlick    schedule 20.08.2016
comment
Спасибо @MrFlick. Как мне присвоить переменную тогда? Я пробовал eval(snm)‹, но это не сработало.   -  person atclaus    schedule 20.08.2016
comment
Также не используйте eval(). Обычно вам просто нужно разумно использовать именованные списки. Это то, с чем большинство функций лучше всего работают, а не с набором отдельных переменных. Если вам нужны две коллекции, одна для выпускного и для начала, используйте x <- list(grad=list(), start=list()). Затем вы можете сделать x[["grad"][[1]] <- ggplot(...) или что-то еще.   -  person MrFlick    schedule 20.08.2016
comment
Спасибо @MrFlick, теперь, когда я это вижу, это имеет большой смысл.   -  person atclaus    schedule 20.08.2016


Ответы (2)


Несмотря на длинный фрагмент кода, ваш вопрос действительно не ясен. Вы пытаетесь сделать что-то подобное?

library(ggplot2)
library(gridExtra)

set.seed(1492)
TDSF <- data.frame(Graduation=sample(1950:2010, 30),
                   Donation=sample(300:10000, 30))

snm <- mapply(function(x, title) {
  ggplot(TDSF, aes_(x=as.name(x))) + 
    geom_histogram() + 
    labs(title=title) 
}, c("Graduation", "Donation"), c("A", "B"), SIMPLIFY=FALSE)

do.call(grid.arrange, snm)
person hrbrmstr    schedule 20.08.2016
comment
Извиняюсь. Новичок в R и Stack Overflow (по крайней мере, публикация). Это совершенно другой подход, чем я делал, но он может работать лучше. Тем не менее, я пытаюсь назвать что-то в snm, но пусть snm изменится. Итак, я заканчиваю с grad[[1]], grad[[[2]] и затем init[[1]], init[[2]] - person atclaus; 20.08.2016
comment
Пересмотрел мой ОП, чтобы, надеюсь, иметь больше смысла - person atclaus; 20.08.2016
comment
Решил это. Я не был знаком с aes_ по сравнению с простым aes и пропустил это в вашем примере. - person atclaus; 22.08.2016

То, что я хотел сделать изначально, невозможно именно таким образом. Однако, основываясь на отзывах, я смог создать список списков ggplots. Это сжимает мой вывод до 1 переменной вместо двух, на которые я ориентировался. Вместо start[[1]] для построения первого графика я использую plot[["start"]][[1]]. Имеет смысл, когда вы читаете это, но не так, как я ожидал. Я родом из VBA и Python, поэтому R — новый формат.

Mapply также невероятно более мощный/простой подход, чем я изначально делал, так что спасибо за этот вклад.

library(ggplot2)
library(gridExtra)

set.seed(1492)
TDSF <- data.frame(Graduation=sample(1950:2010, 30),
                   Donation=sample(300:10000, 30),
                   Start.Year=sample(1950:2010,30),
                   State=sample(state.abb,30,replace=TRUE))

    plot<-mapply(function(snm,nm) list(
      {ggplot(data=TDSF, aes_q(x=as.name(nm)))+geom_histogram()+labs(title=paste("Number of People per",snm,"Year"))},
      {ggplot(data=TDSF, aes_q(x=as.name(nm),weights=~Donation))+geom_bar()+labs(title=paste("Donations by",snm,"Year"))},
      {ggplot(data=TDSF, aes(x=State,weights=Donation))+geom_bar()+labs(title="Donations by State")+scale_y_sqrt()}
    ), c("grad","start"),c("Graduation","Start.Year"),SIMPLIFY = FALSE)

    do.call(grid.arrange,plot[["grad"]])
    do.call(grid.arrange,plot[["start"]])
person atclaus    schedule 22.08.2016