Цикл Lapply и for дает другой результат при динамическом создании графиков - PullRequest
0 голосов
/ 23 ноября 2018

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

Удивительно, но в то время как lapply дает ожидаемый результат, графики, созданные с помощью цикла for, в итоге содержат все те же данные y.

Вот воспроизводимый пример:

library(ggplot2)
library(gridExtra)

gen.plot <- function(df, x.colName, y.colName, title,
                            movavg.period) {
  # print(y.colName)
  p <- ggplot(df, aes(x = df[[x.colName]],
                      y = df[[y.colName]])) +
    geom_line() +
    xlab("Time") +
    ylab("Value") +
    ggtitle(title)

  return(p)
}

titles <- c("down", "mid", "up")
df <- data.frame(tick = seq(0, 10, 1),
                 down = seq(2, 1, -0.1),
                 mid = rep(3, 11),
                 up = seq(5,6, 0.1))

plots.list <- list()
for(t in titles) {
  plots.list[[length(plots.list) + 1]] <- gen.plot(df, "tick", 
                                            t, t, 2)
}
grid.arrange(grobs = plots.list, nrow = 3)

plots.list <- lapply(titles, FUN =  function(t, lapply.df) {
  gen.plot(lapply.df, "tick", 
        t, t, 2)
}, lapply.df = df)

grid.arrange(grobs = plots.list, nrow = 3)

Теперь, когда это становится действительно странным, это то, что если вы раскомментируете вызов print в функции, которая выводит переменную y.colName , цикл forработает как положено.Но это работает, только если вы распечатываете эту конкретную переменную, а не любую другую переменную функции.Кроме того, как вы можете видеть в коде, переменная y.colName используется в заголовке графика, и заголовок корректен в каждом графике.

Кроме того, я имеюпопытался извлечь код из функции, но он дает те же результаты, и трюк с вызовом print больше не работает.

Я не могу опубликовать изображение без 10 репутации, поэтому ссылки придется делать.

Вот что я получаю с помощью петли for: forloop

Вот что я получаю с lapply: lapply

Вот мой sessionInfo():

R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Ireland.1252  LC_CTYPE=English_Ireland.1252   
[3] LC_MONETARY=English_Ireland.1252 LC_NUMERIC=C                    
[5] LC_TIME=English_Ireland.1252    

attached base packages:
  [1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
  [1] gridExtra_2.3 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] labeling_0.3     colorspace_1.3-2 scales_0.5.0     compiler_3.4.3  
[5] lazyeval_0.2.0   plyr_1.8.4       tools_3.4.3      pillar_1.2.1    
[9] gtable_0.2.0     tibble_1.4.2     yaml_2.1.14      Rcpp_0.12.16    
[13] grid_3.4.3       rlang_0.2.0      munsell_0.4.3 

Пожалуйста, если вы понимаете, что здесь происходит, объясните мне, помогите мне вернуться ко сну.

1 Ответ

0 голосов
/ 23 ноября 2018

Попробуйте:

gen.plot <- function(df, x.colName, y.colName, title,
                     movavg.period) {
  # print(y.colName)
  p <- ggplot(df, aes_string(x = x.colName,
                             y = y.colName)) +
    geom_line() +
    xlab("Time") +
    ylab("Value") +
    ggtitle(title)

  return(p)
}

Он должен давать вам результаты и корректировать, какой бы метод вы ни использовали для его реализации (т. Е. Цикл lapply или for).Использование ggplot2 таким образом позволяет вам указывать имена переменных, используя строку.И вы должны указывать имена переменных и не давать aes весь столбец из фрейма данных.

...