使用ggplot和R绘制多个图层(条形图)

时间:2016-02-18 17:20:54

标签: r excel graph ggplot2

我正在尝试使用列出全年库存和销售额的数据重新创建我在Excel中创建的条形图。这是我在Excel中的图表:

注意:平均销售率是条形图中13个月的总销售额/总库存。

我是通过R和ggplot包来做到这一点的。我对此很新,但这是我迄今为止所做的:

library(lubridate)
library(ggplot2)
library(scales)
library(reshape2)

COdata <- read.csv("C:/.../CenterOne.csv")

# Grab related data
# VIN refers to a unique inventory identifier for the item
# First Launch Date is what I use to count my inventory for the month
# Sale Date is what I use to count my sales for the month

DFtest <- COdata[, c("VIN", "First.Launch.Date", "Sale.Date")]

以下是数据外观的快照:

> head(DFtest)
                VIN First.Launch.Date       Sale.Date
1 4T1BF1FK4CU048373   22/04/2015 0:00                
2 2T3KF4DVXCW108677   16/03/2015 0:00                
3 4T1BF1FKXCU035935   19/03/2015 0:00 20/03/2015 0:00
4 JTDKN3DU3B1465796   16/04/2015 0:00                
5 2T3YK4DV8CW015050                                  
6 4T1BF1FK5CU599556   30/04/2015 0:00                

我将日期转换为适当的格式,删除小时/秒并将它们分成每月一次:

DFtest$First.Launch.Date <- as.Date(DFtest$First.Launch.Date, format = "%d/%m/%Y")
DFtest$Sale.Date <- as.Date(DFtest$Sale.Date, format = "%d/%m/%Y")
DFtest$month.listings <- as.Date(cut(DFtest$First.Launch.Date, breaks = "month"))
DFtest$month.sales <- as.Date(cut(DFtest$Sale.Date, breaks = "month"))

> head(DFtest)
                VIN First.Launch.Date  Sale.Date month.listings month.sales
1 4T1BF1FK4CU048373        2015-04-22       <NA>     2015-04-01        <NA>
2 2T3KF4DVXCW108677        2015-03-16       <NA>     2015-03-01        <NA>
3 4T1BF1FKXCU035935        2015-03-19 2015-03-20     2015-03-01  2015-03-01
4 JTDKN3DU3B1465796        2015-04-16       <NA>     2015-04-01        <NA>
5 2T3YK4DV8CW015050              <NA>       <NA>           <NA>        <NA>
6 4T1BF1FK5CU599556        2015-04-30       <NA>     2015-04-01        <NA>

平均线图 - 我尝试创建一个

DF_Listings = data.frame(table(format(DFtest$month.listings)))
DF_Sales = data.frame(table(format(DFtest$month.sales)))
DF_Merge <- merge(DF_Listings, DF_Sales, by = "Var1", all = TRUE)

> head(DF_Listings)
        Var1 Freq
1 2014-12-01   77
2 2015-01-01  886
3 2015-02-01  930
4 2015-03-01 1167
5 2015-04-01 1105
6 2015-05-01 1279

DF_Merge$Avg <- DF_Merge$Freq.y / DF_Merge$Freq.x

> head(DF_Merge)
        Var1 Freq.x Freq.y       Avg
1 2014-12-01     77     NA        NA
2 2015-01-01    886    277 0.3126411
3 2015-02-01    930    383 0.4118280
4 2015-03-01   1167    510 0.4370180
5 2015-04-01   1105    309 0.2796380
6 2015-05-01   1279    319 0.2494136

ggplot(DF_Merge, aes(x=Var1, y=Avg, group = 1)) +
  stat_smooth(aes(x = seq(length(unique(Var1)))),
              se = F, method = "lm", formula = y ~ poly(x, 11)) 

enter image description here

条形图

dfm <- melt(DFtest[ , c("VIN", "First.Launch.Date", "Sale.Date")], id.vars = 1)
dfm$value <- as.Date(cut(dfm$value, breaks = "month"))

ggplot(dfm, aes(x= value, width = 0.4)) + 
  geom_bar(aes(fill = variable), position = "dodge") +
  scale_x_date(date_breaks = "months", labels = date_format("%m-%Y")) +
  theme(axis.text.x=element_text(hjust = 0.5)) +
  xlab("Date") + ylab("")

enter image description here

所以我设法制作了一些让我有几个问题的情节:

  1. 如何使用ggplot将它们组合成一个单独的图形?

  2. 请注意我的条形图在第一个月和上个月的空白情况如何?如何删除它(确切地说,如何从x轴移除11-2014和01-2016)?

  3. 在我的条形图中,2014年1月没有销售,因此库存栏占用更大的空间。如何减小尺寸以适应图表的其余部分?

  4. 如何将x轴从使用日期作为数字(即12-2014)更改为使用月份(即2014年12月)来改变x轴。我已尝试使用as.yearmon,但这不适用于我的ggplot函数的scale_x_date部分。

  5. 还有平均销售率线的问题,我可以放心地假设我会使用geom_hline(),但我不知道如何处理这个问题。

1 个答案:

答案 0 :(得分:3)

使用mtoto关于利用googleVis的建议,我重新创建了图表:

# Testing Google Vis
mytest <- DF_Merge

library(zoo)
library(plyr) # to rename columns
library(googleVis)

mytest$Var1 <- as.yearmon(mytest$Var1)
mytest$Var1 <- as.factor(mytest$Var1) # googleVis cannot understand yearmon "class" so change it to factor

# Rename columns to ensure comprehension
mytest <- rename(mytest, c("Var1"="Date", "Freq.x"="Listings", "Freq.y"="Sales", "Avg"="Sales Rate"))

# Prepare for values to be displayed right on the plot
mytest$Listings.annotation <- mytest$Listings
mytest$Sales.annotation <- mytest$Sales
mytest$`Sales Rate.annotation` <- percent(mytest$`Sales Rate`) #Googlevis automatically understands that .annotation is used to display values in the graph

# Create average rate line
mytest$`Sales Rate` <- as.numeric(mytest$`Sales Rate`)
mytest$AvgRate <- (sum(mytest$Sales) / sum(mytest$Listings))
mytest <- rename(mytest, c("AvgRate"="Average Sales Rate"))


# Create the annotation for the average line
mytest$`Average Sales Rate.annotation` <- mytest$`Average Sales Rate`
x = nrow(mytest) - 1
mytest$`Average Sales Rate.annotation`[1:x] = "" # Ensures only the last row in this column has a value
mytest$`Average Sales Rate.annotation` <- as.numeric(mytest$`Average Sales Rate.annotation`, na.rm = TRUE)
mytest$`Average Sales Rate.annotation`[nrow(mytest)] <- percent(mytest$`Average Sales Rate.annotation`[nrow(mytest)]) # Transforms only the last row to a proper percentage!

# Plot the graph
column <- gvisComboChart(mytest, xvar= "Date",
                         yvar=c("Listings", "Listings.annotation", "Sales", "Sales.annotation", "Sales Rate", "Sales Rate.annotation", "Average Sales Rate",
                                "Average Sales Rate.annotation"),
                         options=list(seriesType="bars",
                                      series="[{type: 'bars', targetAxisIndex:0, color:'orange'},
                                      {type: 'bars', targetAxisIndex:0, color:'green'},
                                      {type: 'line', targetAxisIndex:1, color:'red'},
                                      {type: 'line', targetAxisIndex:1, color:'purple', lineDashStyle:[2,2,20,2,20,2]}]",
                                      vAxes="[{format:'decimal', textPosition: 'out', viewWindow:{min:0, max:200}}, 
                                      {format:'percent', textPosition: 'out', viewWindow:{min:0, max:1}}]",
                                      hAxes="[{textPosition: 'out'}]",
                                      legend = "bottom",
                                      curveType="function",
                                      width=1500,
                                      height=800))

plot(column)

变量本来可以被更好地命名,但是我能够得到我想要的最终结果:

enter image description here