【问题标题】:In R, I want to plot all of data frame's columns (but last one) against its last columns using ggplop in a for loop. It doesn't work在 R 中,我想在 for 循环中使用 ggplop 绘制所有数据框的列(但最后一个)与其最后一列。它不起作用
【发布时间】:2020-12-03 16:45:13
【问题描述】:

我有一个数据框,我想使用 ggplot 绘制它的所有列,但最后一列与最后一列相对。此后,我使用 for 循环和 grid.arrange 来获得一行 13 个图。但是输出只是在整个行中重复一个图。 也就是说,只需根据第 14 列绘制第 13 列(最后一次迭代)。

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]] ###这是个问题。

您能告诉我如何解决它吗?

【问题讨论】:

  • 这几乎肯定是一个“ggplot 懒惰地评估”问题> 当for 循环结束并且ggplot 最终评估时,所有调用都使用索引变量的相同(最终)值.最简单的解决方案是将for 循环转换为lapply 或类似的。这将强制进行评估。

标签: r ggplot2 plot


【解决方案1】:

Limey 的评论可能是您感到沮丧的原因,他的解决方案也会奏效。因此,我不会专注于解决您的问题,而是建议使用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

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2020-05-11
    • 1970-01-01
    • 2021-09-04
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多