【问题标题】:ggplot for loop outputs all the same graphggplot for loop 输出所有相同的图形
【发布时间】:2017-05-30 16:23:26
【问题描述】:

我编写了一个 for 循环,它遍历数据框的列,并使用 ggplot 为每一列生成一个图形。问题是输出的图都是一样的——它们都是最后一列的图。

我使用的代码是:

library(gridExtra)
library(ggplot2)
test1 <- c("Person1","Person2","Person3","Person4","Person5")
test2 <- as.data.frame(c(1,2,3,4,5))
test3 <- as.data.frame(c(2,2,2,2,2))
test4 <- as.data.frame(c(1,3,5,3,1))
test5 <- as.data.frame(c(5,4,3,2,1))
test <- cbind(test1,test2,test3,test4,test5)
rm(test1,test2,test3,test4,test5)
colnames(test) <- c("Person","var1","var2","var3","var4")

for(i in 2:5){
  nam <- paste0("graph", i-1)
  graph_temp <- ggplot(test, aes(Person, test[,i])) + geom_bar(stat = "identity")
  assign(nam, graph_temp)
}
grid.arrange(graph1, graph2, graph3, graph4, ncol=2)

我的目标是这段代码的情节:

library(gridExtra)
library(ggplot2)
test1 <- c("Person1","Person2","Person3","Person4","Person5")
test2 <- as.data.frame(c(1,2,3,4,5))
test3 <- as.data.frame(c(2,2,2,2,2))
test4 <- as.data.frame(c(1,3,5,3,1))
test5 <- as.data.frame(c(5,4,3,2,1))
test <- cbind(test1,test2,test3,test4,test5)
rm(test1,test2,test3,test4,test5)
colnames(test) <- c("Person","var1","var2","var3","var4")

graph1 <- ggplot(test, aes(Person, test[,2])) + geom_bar(stat = "identity")
graph2 <- ggplot(test, aes(Person, test[,3])) + geom_bar(stat = "identity")
graph3 <- ggplot(test, aes(Person, test[,4])) + geom_bar(stat = "identity")
graph4 <- ggplot(test, aes(Person, test[,5])) + geom_bar(stat = "identity")
grid.arrange(graph1, graph2, graph3, graph4, ncol=2)

我知道有一个 similar question 可以将 ggplots 保存在 for 循环中,但我还没有设法让那个解决这个问题。

【问题讨论】:

  • 你正在覆盖graph_temp,所以只有最后一个被绘制。学习使用列表。如果可以,您应该避免使用 for 循环,尽管 lapply 只是伪装的 for 循环。至少它可以保护您免受这种典型的新手错误的影响。
  • 谢谢,虽然你是graph_temp 有问题吗?我认为它会在 for 循环的每次迭代中将其写入另一个对象(例如,graph_tempgraph1graph_tempgraph2 等)。此外,为了将来参考,在一个关于建立社区技能的网站上,诸如“学习使用列表”之类的陈述没有详细说明和“典型的新手错误”并没有太大帮助。对于以建设性方式所说的相同内容,我建议您参考下面同行的回答。我认为这是 Stack Overflow 上的一个普遍问题,相对的“新手”可能会害怕不提问。
  • 你需要了解惰性求值。这不是该函数的问题,而是使用 for 循环的问题。我们曾经都是新手。您首选的答案并未解释您的错误原因,也没有为您提供未来使用何种策略的建议。

标签: r ggplot2


【解决方案1】:

这里有一个更简洁的方式来生成你的例子:

df <- data.frame(
  Person = paste0("Person", 1:5),
  var1 = c(1,2,3,4,5),
  var2 = c(2,2,2,2,2),
  var3 = c(1,3,5,3,1),
  var4 = c(5,4,3,2,1)
)

现在,关于你的情节。

最佳解决方案

将数据框重塑为“长”格式,然后使用构面:

library(ggplot2)
library(tidyr)
gather(df, var, value, -Person) %>%
  ggplot(aes(Person, value)) +
    geom_bar(stat = "identity") +
    facet_wrap(~ var)

否则……

如果您必须坚持使用与您发布的内容相似的数据结构,请使用aes_string

library(ggplot2)
library(gridExtra)

g <- lapply(1:4, function(i) {

  ggplot(df, aes_string("Person", paste0("var", i))) +
    geom_bar(stat = "identity")

})
grid.arrange(grobs = g, ncol = 2)

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多