R:处理和绘制分组数据

时间:2013-06-17 15:43:05

标签: r ggplot2

这是关于此问题的后续问题:R: plot multiple lines in one graph

在那里,我使用了部分数据来绘制多行图形。现在我想在一个网格中绘制多个图形,因为我已经对数据进行了分组。 现在我正在这样做,为每组数据创建数据帧,然后为每个数据帧创建一个图表,并使用gridd.arrange()组合这些数据帧 但是,我想知道我是否可以将分组数据作为1个数据集处理,而不是创建所有这些单独的表?

我的数据结构如下:

          Category1    Category2    Category3
Company   2011   2013  2011   2013  2011   2013
Company1  300    350   290    300   295    290
Company2  320    430   305    301   300    400
Company3  310    420   400    305   400    410

那么有没有办法立即处理这个问题并绘制3个图表(每个类别)以及每个公司年度(2011年和2013年)的行?

2 个答案:

答案 0 :(得分:5)

您一定要学习如何构建数据以及如何make a reproducable example。以这种非结构化格式处理数据真的很难。不仅是为了你,也为了我们。

mdf <- read.table( text="Company   2011   2013  2011   2013  2011   2013
Company1  300    350   290    300   295    290
Company2  320    430   305    301   300    400
Company3  310    420   400    305   400    410", header = TRUE, check.names=FALSE )

library("reshape2")
cat1 <- melt(mdf[c(1,2,3)], id.vars="Company", value.name="value", variable.name="Year")
cat1$Category <- "Category1"
cat2 <- melt(mdf[c(1,4,5)], id.vars="Company", value.name="value", variable.name="Year")
cat2$Category <- "Category2"
cat3 <- melt(mdf[c(1,6,7)], id.vars="Company", value.name="value", variable.name="Year")
cat3$Category <- "Category3"
mdf <- rbind(cat1, cat2, cat3)

head(mdf)
   Company Year value  Category
1 Company1 2011   300 Category1
2 Company2 2011   320 Category1
3 Company3 2011   310 Category1
4 Company1 2013   350 Category1
5 Company2 2013   430 Category1
6 Company3 2013   420 Category1

如果类别数量非常大,这当然可以自动化:

library( "plyr" )
mdf <- adply( c(1:3), 1, function( cat ){
  tmp <- melt(mdf[ c(1, cat*2, cat*2+1) ], id.vars="Company", value.name="value", variable.name="Year")
  tmp$Category <- paste0("Category", cat)
  return(tmp)
} )

但如果你可以避免从一开始就反复推送所有这些数据,你应该这样做。

使用构面

ggplot2内置支持显示相同类型数据的分面图,如果它们可以是一个(或多个)变量的子集。请参阅? facet_wrap? facet_grid

ggplot(data=mdf, aes(x=Year, y=value, group = Company, colour = Company)) +
    geom_line() +
    geom_point( size=4, shape=21, fill="white") +
    facet_wrap( "Category" )

enter image description here

获取个别情节

或者,您可以按相应变量对data.frame进行子集化,并将各个图存储在列表中:

librayr("plyr")
ll <- dlply( mdf, "Category", function(x){
        ggplot(data=x, aes(x=Year, y=value, group = Company, colour = Company)) +
          geom_line() +
          geom_point( size=4, shape=21, fill="white")
})
ll[["Category1"]]

答案 1 :(得分:0)

至少对于ggplot2,您需要使用 reshape2 包,以便将数据转换为稍微不同的格式。

让我们假设你有一个像这样的data.frame:

test <- structure(list(Company = structure(1:3, .Label = c("Company1", 
"Company2", "Company3"), class = "factor"), X2011.1 = c(300L, 
320L, 310L), X2013.1 = c(350L, 430L, 420L), X2011.2 = c(290, 
305, 400), X2013.2 = c(300, 301, 305), X2011.3 = c(295, 300, 
400), X2013.3 = c(290L, 400L, 410L)), .Names = c("Company", "X2011.1", 
"X2013.1", "X2011.2", "X2013.2", "X2011.3", "X2013.3"), class = "data.frame", row.names = c(NA, 
-3L))

暂时忽略丑陋,看起来像:

  Company  X2011.1 X2013.1 X2011.2 X2013.2 X2011.3 X2013.3
  Company1     300     350     290     300     295     290
  Company2     320     430     305     301     300     400
  Company3     310     420     400     305     400     410

如果我们使用melt()函数,我们可以看起来像这样:

melt(test) -> test.melt

test.melt

Using Company as id variables
    Company variable value
1  Company1  X2011.1   300
2  Company2  X2011.1   320
3  Company3  X2011.1   310
4  Company1  X2013.1   350
5  Company2  X2013.1   430
6  Company3  X2013.1   420
7  Company1  X2011.2   290
8  Company2  X2011.2   305

然后使用公司或variable作为ggplot2的分组因子。显然你会想要更明智地命名这些。 :)

e.g。你可以做到

ggplot(melt(test)) + geom_bar(aes(x = Company, y = value, fill = variable), stat = "identity", position = "dodge")

或其他什么。