在R中使用循环的多个图

时间:2014-01-02 21:29:26

标签: r loops plot dataframe

我仍然试图利用循环在R中绘图。我想在下面的数据框中根据不同的名称绘制(任何可视化数据的图表)z_2对z_2第x_1栏。

x_1 <- c("A1", "A1","A1", "B10", "B10", "B10","B10", "C100", "C100", "C100")


z_1 <- rnorm(10, 70) 

z_2 <- rnorm(10, 1.7)

A <- data.frame(x_1, z_1, z_2)

因此,我想最终得到三个不同的情节;一个用于A1类,一个用于B10,另一个用于C100。我可以使用三个不同的代码执行此操作,但我希望能够使用循环或任何其他单个代码在同一页面上执行所有三个绘图。实际上,我有一个大型数据集(4,000行),并希望在页面上绘制几个ID(比如页面上的5个)。

我希望这是有道理的。谢谢你的帮助。

我试图单独绘制它们:

A1的

data_A1 <- A[which(A$x_1 == "A1"), ]
plot(data_A1$z_2, data_A1$z_1)

我也尝试过这样的东西,但收到错误消息

for ( i in A$x_1[[i]]){

plot(A[which(A$x_1==A$x_1[[i]]), ], aspect = 1)
}

4 个答案:

答案 0 :(得分:16)

循环的简单方法是

for (cat in unique(x_1)){
  d <- subset(A, x_1 == cat)
  plot(d$z_1, d$z_2)
}

unique(x_1)为您提供x_1的所有唯一值。然后,对于这些值中的每一个,获得相应的子集并使用该子集进行绘图。

答案 1 :(得分:13)

只是为了理解原始代码不起作用的原因:

设置数据正常

x_1 <- c("A1", "A1", "A1", "B10", "B10", "B10","B10", "C100", "C100", "C100")
z_1 <- rnorm(10, 70) 
z_2 <- rnorm(10, 1.7)
A <- data.frame(x_1, z_1, z_2)

单个情节工作正常,但正如我在评论中所说,which是不必要的

data_A1 <- A[which(A$x_1 == "A1"), ] # your way
plot(data_A1$z_2, data_A1$z_1)

data_A1 <- A[A$x_1 == "A1", ]    # deleting which() makes it cleaner
with(data_A1, plot(z_2, z_1))    # you can also use with() to save typing

现在是for循环。让我们回顾一下R中的一个简单的for循环(非常接近?"for"中的例子):

for (i in 1:5) {
   print(1:i)
}

非常简单,1:5c(1, 2, 3, 4, 5),因此首先i1,然后为2,等等。您的for循环首先出现问题行:

for (i in A$x_1[[i]]) { ## already a problem

首先iA$x_1[[i]]?这不起作用,i尚未定义。此外,A$x_1是一个向量,而不是列表,因此您不应该使用[[对其进行子集化。但是我们还不想要一个子集,我们想要一个值为i的向量。在这种情况下我们想要的是for (i in c("A1", "B10", "C100")),但我们也希望以编程方式进行,而不是键入所有不同的可能性。有几种常见的方法可以实现这一目标:

unique(A$x_1) # as in Mark's solution
levels(A$x_1) # works because A$x_1 is a factor

我们可以在in之后放置其中任何一个表达式。我在剧情电话中将您的[[更改为[[[仅供参考。我还拿出了不必要的which()

for (i in unique(A$x_1)) {   # this line is good
    plot(A[A$x_1==A$x_1[i], ], aspect = 1)  # still a problem
}

让我们自己提醒i正在采取什么价值观:"A1""B10""C100"。什么是A$x_1 == A$x_1["A1"]会给出什么?没什么用的。

for (i in unique(A$x_1)) {  
    plot(A[A$x_1 == i, ], aspect = 1)  # getting there
}

上面的代码描绘了一些东西,它很整洁,但它不是你想要的。有一堆警告,他们都告诉我们aspect不是一个有效的参数,所以我们将删除它。看一下情节,你会发现它正在绘制3个变量,因为我们还没有告诉它在x和y轴上放什么。

for (i in unique(A$x_1)) {   
    plot(A[A$x_1==i, "z_2"], A[A$x_1==i, "z_1"])  # z_2 on x, z_1 on y 
}   # Works!!!

请注意,这几乎与Mark的答案相同。您不必在for循环中使用ij,而是使用cat。使用更具描述性的名称是一种很好的做法。 现在让我们想起一点:

for (i in unique(A$x_1)) {   
    plot(A[A$x_1==i, "z_2"], A[A$x_1==i, "z_1"],
         xlim = range(A$z_2), ylim = range(A$z_1), # base the axes on full data range
         main = paste("Plot of", i))  # Give each a title
}

下次:不要忘记您可以运行一小段代码来查看它们是什么。如果你有for (i in A$x_1[[i]])这样的行,你不确定它是否正确,请在控制台输入A$x_1[[i]],希望这可以帮助你弄清楚你没有定义i,所以你将它改为

for (i in A$x_1)

然后你运行A$x_1并意识到它的长度是10.你想要3个图形,而不是10个,所以你需要i来获取3个值,所有这些都是不同的,等等。

答案 2 :(得分:3)

也许你不需要循环。尝试使用ggplots facet_grid()。 以下是documentation,其中包含大量示例。

library(ggplot2)
library(reshape2)

melted_a <- melt(A)


ggplot(melted_a, aes(variable, value)) +
  geom_jitter() +
  facet_grid(. ~ x_1)

ggplot(melted_a, aes(variable, value)) +
  geom_jitter() +
  facet_grid(variable ~ x_1)

修改 也许这解决了这个问题。但是,如果您需要执行许多具有相似结构的绘图,则可以创建一个函数并使用aes_string()而不是aes()。 注意:我不是编写函数的专家,所以可能有人可以编辑和改进它。 (未经测试)

ggplot_fun <- function(data, x, y, rowfacet, colfacet, ...){
  p <- ggplot(data, aes_string(x, y))
  p <- p + geom_jitter()
  p <- p + facet_grid(as.formula(sprintf("%s ~ %s", rowfacet, colfacet))
}

ggplot_fun(melted_a, variable, value, variable, x_1)

从这个question获取的想法。

答案 3 :(得分:1)

您还可以调整数据,例如我在这里做的......

如果我想要日期图和xlab,ylab和情节标题有特定细节......

 for ( i in 1:length(unique(wheeldata$Date)) ){
     d <- subset( wheeldata, Date == unique ( wheeldata$Date )[i] )
     plot(d$X, d$Y, xlab = "X", ylab = "Y", main = paste0("Date: ",  unique(d$Date)) )
 }