В R я хочу отобразить все столбцы фрейма данных (кроме последнего) против его последних столбцов, используя ggplop в цикле for . Это не работает

#r #ggplot2 #plot

#r #ggplot2 #график

Вопрос:

У меня есть фрейм данных, и я хочу отобразить все его столбцы, кроме последнего, против его последних столбцов, используя ggplot. После этого я использую цикл for и grid.расположите так, чтобы получился ряд из 13 графиков. Но результат — это просто повторение одного графика по всей строке. то есть просто сопоставьте 13-й столбец (последняя итерация) с 14-м столбцом.

 times1<-times[timeindex] ### this is a vector

mat_ind    <- matrix(0, nrow=120,ncol=13) 



mat_ind [,1] <- logBF_Apollo_1[,1]  ### all logBF_Apollo_1,..., logBF_Apollo_1 are matrices

mat_ind [,2] <- logBF_Apollo_2[,1]

mat_ind [,3] <- logBF_Apollo_3[,1]

mat_ind [,4] <- logBF_Apollo_4[,1]

mat_ind [,5] <- logBF_Apollo_5[,1]

mat_ind [,6] <- logBF_Apollo_6[,1]

mat_ind [,7] <- logBF_Apollo_7[,1]

mat_ind [,8] <- logBF_Apollo_8[,1]

mat_ind [,9] <- logBF_Apollo_9[,1]

mat_ind [,10] <- logBF_Apollo_10[,1]

mat_ind [,11] <- logBF_Apollo_11[,1]

mat_ind [,12] <- logBF_Apollo_12[,1]

mat_ind [,13] <- logBF_Apollo_13[,1]


mat_ind<- data.frame(mat_ind,times1)

library(ggplot2)

library(gridExtra)



for(i  in 1:13 ){
  p[[i]] <-ggplot(mat_ind, aes(x = times1, y = mat_ind[,i]))  
  geom_line()  ylab("")  coord_flip()  
  xlab("")}


figure1 <- grid.arrange(p[[1]],p[[2]],p[[3]],p[[4]],p[[5]],p[[6]],p[[7]],p[[8]],p[[9]],
                   p[[10]],p[[11]],p[[12]],p[[13]], ncol = 13, nrow =1)


figure
 

Результаты просто повторяют последнюю итерацию цикла for.
то есть проблема заключается в том, что вывод цикла for:

p[[1]]=p[[2]]=…=p[[13]] ### это проблема.

Не могли бы вы, пожалуйста, дать мне знать, как я могу это исправить?

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

1. Это, безусловно ggplot , проблема «ленивой оценки»> Когда for цикл заканчивается и ggplot в конечном итоге завершается, все вызовы используют одно и то же (конечное) значение переменной index . Самое простое решение — преобразовать for цикл в lapply или аналогичный. Это приведет к принудительной оценке.

Ответ №1:

Комментарий Лайми, вероятно, является причиной вашего разочарования, и его решение тоже сработало бы. Поэтому я не собираюсь сосредотачиваться на решении вашей проблемы, а скорее хотел бы предложить использовать facet_wrap() вместо упорядочивания всех участков с grid.arrange() помощью , основываясь на впечатлении, что все ваши участки в любом случае имеют схожую структуру.

Я предполагаю, что у вас есть набор переменных с одинаковыми именами, например:

 library(ggplot2)

times <- 1:120

logBF_Apollo_1 <- matrix(rnorm(prod(120, 2)), nrow = 120)
logBF_Apollo_2 <- matrix(rnorm(prod(120, 2)), nrow = 120)
logBF_Apollo_3 <- matrix(rnorm(prod(120, 2)), nrow = 120)
logBF_Apollo_4 <- matrix(rnorm(prod(120, 2)), nrow = 120)
logBF_Apollo_5 <- matrix(rnorm(prod(120, 2)), nrow = 120)
# To lazy to type the rest
 

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

 first_columns <- lapply(1:5, function(i) {
  sym <- as.symbol(paste0("logBF_Apollo_", i))
  eval(sym)[, 1]
})
mat_ind <- do.call(cbind, first_columns)
 

Что мы сделаем дальше, так это немного отформатируем имена, добавим times столбец и преобразуем данные из широкого формата в длинный формат.

 colnames(mat_ind) <- paste0("pretty_name_", seq_len(ncol(mat_ind)))
mat_ind <- data.frame(mat_ind, times)
df <- tidyr::pivot_longer(mat_ind, dplyr::starts_with("pretty_name"))
 

Затем становится довольно легко сгенерировать 1 график, содержащий все панели.

 ggplot(df, aes(times, value))  
  geom_line()  
  facet_wrap(~ name, ncol = ncol(mat_ind) - 1) # -1 because of the times-column
 

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