R语言 如何将ggplot的环境存储到列表中?

q5lcpyga  于 2023-04-03  发布在  其他
关注(0)|答案(2)|浏览(96)

我在for循环中生成各种图并将它们存储在列表中。想法是脚本的用户只需要提供一个dataframe,并且脚本自动为该dataframe的每一列执行条形图。问题是我采用的是动态代码,因此如果循环的每一步的环境没有存储在列表中,然后当我调用列表中的每个元素时,我总是得到相同的图(对应于 Dataframe 的最后一列)。
下面是一个测试数据框:

test<-data.frame(color=c('blue', 'blue', 'red', 'red', 'yellow', 'green', 'green', 'green'),
                 fruit=c('apple', 'apple', 'apple', 'apple', 'banana', 'banana', 'blueberry', 'orange'),
                 letter=c('A', 'A', 'A', 'A', 'A','B','C','C'))

这里是我尝试做的循环:

plotList<-list()

for (i in 1:ncol(test)){
  varName<-colnames(test)[i]
  
  newPlot<-ggplot(data=test,aes(x=test[,varName]))+
    geom_bar()
  
  plotList[[i]]<-newPlot
  
}

问题是打印plotList[[1]]plotList[[2]]plotList[[3]]时,总是得到相同的图
我也考虑过使用apply,但是在我的真实的脚本中,我必须在for循环中创建一些中间 Dataframe ,所以它不是那么简单。我也尝试过recordplot(),但是它不起作用。你知道是否有一种方法不仅可以将绘图存储在列表中,而且还可以存储创建绘图的步骤中的环境吗?

kmpatx3s

kmpatx3s1#

另一种选择是使用!!sym来使用带引号的变量varName,如下所示:

plotList<-list()
library(ggplot2)
for (i in 1:ncol(test)){
  varName<-colnames(test)[i]
  
  newPlot<-ggplot(data=test,aes(x=!!sym(varName)))+
    geom_bar()
  
  plotList[[i]]<-newPlot
  
}
plotList
#> [[1]]

#> 
#> [[2]]

#> 
#> [[3]]

创建于2023-03-28带有reprex v2.0.2
请检查本章Quasiquotation

fbcarpbf

fbcarpbf2#

您可以使用.datavarName来索引,(建议使用)

library(ggplot2)
plotList<-list()

for (i in 1:ncol(test)){
  varName<-colnames(test)[i]
  newPlot<-ggplot(data=test,aes(x=.data[[varName]]))+
    geom_bar()
  plotList[[i]]<-newPlot
}

然而,首先,将colnames作为迭代器会更容易:

# use colnames as iterator 
# benefit this safes x name.

for (var in colnames(test)) {
  append(
    plotList,
    ggplot(data=test,aes(x=.data[[var]]))+
      geom_bar()
  )
}

这将生成正确的xlabel标题:颜色、水果、字母
你也可以使用lapply,因为dataframe是列的列表:

plotList <- lapply(test,\(x) ggplot(data=test,aes(x=x))+geom_bar())

你不必预先分配一个列表,因为lapply输出一个列表,你也不必指定一个迭代器,因为它默认使用coulmns。

相关问题