for循环的难以理解的行为

时间:2018-01-02 21:24:43

标签: r loops for-loop ggplot2

我有一个非常奇怪的问题......我正在尝试在循环中创建绘图并将它们放到列表中,之后将它们全部绘制在一个页面上。当我这样做时:

for (i in 1:ncol(df)){ 
   plot[[i]] <- ggplot(df, aes(x = df[,i], y=(..count..)/sum(..count..))) + 
     geom_bar(fill="#003366") + 
     labs(title = dfcolnames[i], x = "Variable Values", y = "Frequency") 
}
return(multiplot(plotlist=plot, cols = 2))

我得到3个相同的图,但是当我没有for循环时这样做:

plot[[1]] <- ggplot(df, aes(x = df[,1], y=(..count..)/sum(..count..))) + geom_bar(fill="#003366") + labs(title = dfcolnames[1], x = "Variable Values", y = "Frequency")
plot[[2]] <- ggplot(df, aes(x = df[,2], y=(..count..)/sum(..count..))) + geom_bar(fill="#003366") + labs(title = dfcolnames[2], x = "Variable Values", y = "Frequency") 
plot[[3]] <- ggplot(df, aes(x = df[,3], y=(..count..)/sum(..count..))) + geom_bar(fill="#003366") + labs(title = dfcolnames[3], x = "Variable Values", y = "Frequency") 
return(multiplot(plotlist=plot, cols = 2))

我得到了正确的情节(三种不同)。我不明白发生了什么......有什么想法吗?

1 个答案:

答案 0 :(得分:4)

问题在于aes()执行延迟评估。传递给aes()的值仅在您实际绘制绘图时才会得到解决。你真的应该只将符号名称传递给aes()。这是因为在循环结束后,i将被固定在循环中的最后一个值,并且您将获得三次相同的绘图。

您可以使用aes_string并循环遍历列名称

plot <- lapply(names(df), function(colname) {
  ggplot(df, aes_string(x = colname, y="(..count..)/sum(..count..)")) + 
           geom_bar(fill="#003366") + 
           labs(title = colname, x = "Variable Values", y = "Frequency") 
})

使用

进行测试
set.seed(10)
df <- data.frame(a=rpois(100, 5), b=rpois(100, 7), c=rpois(100, 3))