#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