Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将ggplot对象存储在R中循环内的列表中_R_Plot_Ggplot2 - Fatal编程技术网

将ggplot对象存储在R中循环内的列表中

将ggplot对象存储在R中循环内的列表中,r,plot,ggplot2,R,Plot,Ggplot2,我的问题类似于;当我在循环中生成plot对象(在本例中为直方图)时,它们似乎都被最近的plot覆盖了 为了调试,我在循环中打印索引和生成的绘图,两者都正确显示。但是,当我查看列表中存储的绘图时,除了标签之外,它们都是相同的 (我正在使用multiplot制作合成图像,但是如果您打印(myplots[[1]]),您会得到相同的结果。 通过打印(myplots[[4]])一次打印一个。) 因为我已经有了一个附加的数据框(与类似问题的海报不同),我不确定如何解决这个问题 (顺便说一句,列类是我在这里近

我的问题类似于;当我在循环中生成plot对象(在本例中为直方图)时,它们似乎都被最近的plot覆盖了

为了调试,我在循环中打印索引和生成的绘图,两者都正确显示。但是,当我查看列表中存储的绘图时,除了标签之外,它们都是相同的

(我正在使用multiplot制作合成图像,但是如果您
打印(myplots[[1]]),您会得到相同的结果。
通过
打印(myplots[[4]])
一次打印一个。)

因为我已经有了一个附加的数据框(与类似问题的海报不同),我不确定如何解决这个问题

(顺便说一句,列类是我在这里近似的原始数据集中的因子,但如果它们是整数,则会出现相同的问题)

以下是一个可复制的示例:

library(ggplot2)
source("http://peterhaschke.com/Code/multiplot.R") #load multiplot function

#make sample data
col1 <- c(2, 4, 1, 2, 5, 1, 2, 0, 1, 4, 4, 3, 5, 2, 4, 3, 3, 6, 5, 3, 6, 4, 3, 4, 4, 3, 4, 
          2, 4, 3, 3, 5, 3, 5, 5, 0, 0, 3, 3, 6, 5, 4, 4, 1, 3, 3, 2, 0, 5, 3, 6, 6, 2, 3, 
          3, 1, 5, 3, 4, 6)
col2 <- c(2, 4, 4, 0, 4, 4, 4, 4, 1, 4, 4, 3, 5, 0, 4, 5, 3, 6, 5, 3, 6, 4, 4, 2, 4, 4, 4, 
          1, 1, 2, 2, 3, 3, 5, 0, 3, 4, 2, 4, 5, 5, 4, 4, 2, 3, 5, 2, 6, 5, 2, 4, 6, 3, 3, 
          3, 1, 4, 3, 5, 4)
col3 <- c(2, 5, 4, 1, 4, 2, 3, 0, 1, 3, 4, 2, 5, 1, 4, 3, 4, 6, 3, 4, 6, 4, 1, 3, 5, 4, 3, 
          2, 1, 3, 2, 2, 2, 4, 0, 1, 4, 4, 3, 5, 3, 2, 5, 2, 3, 3, 4, 2, 4, 2, 4, 5, 1, 3, 
          3, 3, 4, 3, 5, 4)
col4 <- c(2, 5, 2, 1, 4, 1, 3, 4, 1, 3, 5, 2, 4, 3, 5, 3, 4, 6, 3, 4, 6, 4, 3, 2, 5, 5, 4,
          2, 3, 2, 2, 3, 3, 4, 0, 1, 4, 3, 3, 5, 4, 4, 4, 3, 3, 5, 4, 3, 5, 3, 6, 6, 4, 2, 
          3, 3, 4, 4, 4, 6)
data2 <- data.frame(col1,col2,col3,col4)
data2[,1:4] <- lapply(data2[,1:4], as.factor)
colnames(data2)<- c("A","B","C", "D")

#generate plots
myplots <- list()  # new empty list
for (i in 1:4) {
  p1 <- ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 
    geom_histogram(fill="lightgreen") +
    xlab(colnames(data2)[ i])
  print(i)
  print(p1)
  myplots[[i]] <- p1  # add each plot into plot list
}
multiplot(plotlist = myplots, cols = 4)
我认为
mapping:x=data2[,I]
是个问题,但我被难住了!我无法发布图像,因此如果我对问题的解释令人困惑,您需要运行我的示例并查看图表


谢谢

由于所有的表达式都被引用,因此在循环结束时计算的
i
是当时碰巧出现的任何
i
,这是它的最终值。您可以通过
eval(replacement(
在每次迭代中输入正确的值)来解决这个问题

myplots <- list()  # new empty list
for (i in 1:4) {
    p1 <- eval(substitute(
        ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 
          geom_histogram(fill="lightgreen") +
          xlab(colnames(data2)[ i])
    ,list(i = i)))
    print(i)
    print(p1)
    myplots[[i]] <- p1  # add each plot into plot list
}
multiplot(plotlist = myplots, cols = 4)

myplots由于所有的表达式都被引用,因此在循环结束时计算的
i
是当时碰巧出现的
i
的值,这是它的最终值。您可以通过
eval(替换(
ing)在每次迭代中使用正确的值来绕过这个问题

myplots <- list()  # new empty list
for (i in 1:4) {
    p1 <- eval(substitute(
        ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 
          geom_histogram(fill="lightgreen") +
          xlab(colnames(data2)[ i])
    ,list(i = i)))
    print(i)
    print(p1)
    myplots[[i]] <- p1  # add each plot into plot list
}
multiplot(plotlist = myplots, cols = 4)

myplots除了另一个很好的答案之外,这里还有一个解决方案,它使用“正常”的评估而不是
eval
。因为
for
循环没有单独的变量范围(即,它们是在当前环境中执行的)我们需要使用
local
来包装
for
块;此外,我们需要使
i
成为一个局部变量-我们可以通过将其重新分配到自己的名称1:

这有几个优点:它更简单,并且不会扰乱环境(使用循环变量
i



1这似乎令人困惑:
i为什么除了另一个优秀的答案之外,这里有一个解决方案,它使用“正常”的评估而不是
eval
。因为
for
循环没有单独的变量范围(即,它们是在当前环境中执行的)我们需要使用
local
来包装
for
块;此外,我们需要使
i
成为一个局部变量-我们可以通过将其重新分配到自己的名称1:

这有几个优点:它更简单,并且不会扰乱环境(使用循环变量
i



1这似乎令人困惑:为什么
i使用
lappy
也起作用,因为
x
存在于匿名函数环境中(使用
mtcars
作为数据):


plot使用
lappy
也有效,因为
x
存在于匿名函数环境中(使用
mtcars
作为数据):


plot我已经运行了问题和答案中的代码,将
geom_直方图
更改为
geom_条形图
,以避免错误:
error:StatBin需要一个连续的x变量

以下是带有可视化的代码:

问题

#生成绘图

myplots我已经运行了问题和答案中的代码,将
geom_直方图
更改为
geom_条形图
,以避免错误:
错误:StatBin需要一个连续的x变量

以下是带有可视化的代码:

问题

#生成绘图

myplots诊断是正确的,但解决方案有些复杂。在本地上下文中捕获
i
更容易。问题是R中
for
循环没有作用域,因此您需要使用
local
来代替:
for(i in 1:4)local({i=i;…循环的其余部分…})
。自我赋值
i=i
并非偶然-这实际上是需要的。也可以使用不同的变量名。无论如何,使用“正确”将不需要所有这些列出函数而不是
for
,这在R@KonradRudolph
local
中是一个糟糕的语言结构。啊,我忘了一件事:如果使用
local
,则分配给
myplots[[I]]
需要使用
@KonradRudolph如果您想使用
应用
函数之一添加解决方案,似乎在这种情况下也需要替换或本地?另外,是否有理由认为
本地
优于
替换
方式?我更喜欢
本地
,因为它看起来像它正在执行标准评估(当然情况并非如此)。它隐藏了
eval
s和
substitute
s。事实上,如果美学中使用列名,则
lappy
for
都不需要捕捉变量
i
。我将添加一个答案。诊断是正确的,但解决方案有些复杂。捕捉
i
在本地上下文中。问题是R中的
for
循环没有作用域,因此您需要使用
local
来代替:
for(1:4中的i)local({i=i;…循环的其余部分…})
。自我赋值
i=i
不是偶然的-这实际上是需要的。也可以使用不同的变量名。无论如何,如果使用“适当”的列表函数而不是
,则所有这些都是不必要的,因为
是fra
myplots <- vector('list', ncol(data2))

for (i in seq_along(data2)) {
    message(i)
    myplots[[i]] <- local({
        i <- i
        p1 <- ggplot(data2, aes(x = data2[[i]])) +
            geom_histogram(fill = "lightgreen") +
            xlab(colnames(data2)[i])
        print(p1)
    })
}
plot_data_column = function (data, column) {
    ggplot(data, aes_string(x = column)) +
        geom_histogram(fill = "lightgreen") +
        xlab(column)
}

myplots <- lapply(colnames(data2), plot_data_column, data = data2)
plot <- lapply(seq_len(ncol(mtcars)), FUN = function(x) {
  ggplot(data = mtcars) + 
    geom_line(aes(x = mpg, y = mtcars[ , x]), size = 1.4, color = "midnightblue", inherit.aes = FALSE) +
    labs(x="Date", y="Value", title = "Revisions 1M", subtitle = colnames(mtcars)[x]) +
    theme_wsj() +
    scale_colour_wsj("colors6")
})