Use parameter sec.axis of scale_y_continuous()

Simple example

sapply(c("pipeR", "ggplot2", "readr", "lubridate"), require, character.only = TRUE)
 要求されたパッケージ pipeR をロード中です 
 要求されたパッケージ ggplot2 をロード中です 
 要求されたパッケージ readr をロード中です 
 要求されたパッケージ lubridate をロード中です 

 次のパッケージを付け加えます: ‘lubridate’ 

 以下のオブジェクトは ‘package:base’ からマスクされています: 

     date 
    pipeR   ggplot2     readr lubridate 
     TRUE      TRUE      TRUE      TRUE 

Temperature and precipitation in Naha city, Okinawa, Japan (2015)

d <- read_csv("data/ggplot2-two-axis/naha.csv", skip = 5, col_names = c("Date", "Temperature", "Precipitation"), col_types = cols(col_date(format = "%Y/%m"), "d", "_", "_", "d", "_", "_", "_"), locale = locale(encoding = "SJIS"))
head(d)

Precipitation

d %>>% ggplot() + 
  geom_bar(mapping = aes(x = Date, y = Precipitation), stat = "identity") + 
  ylab("Precipitation (mm)")

Temperature

d %>>% ggplot() + 
  geom_point(mapping = aes(x = Date, y = Temperature)) + 
  geom_line(mapping = aes(x = Date, y = Temperature)) + 
  ylab(expression("Temperature ("~degree~"C)"))

Range of data

summary(d)
      Date             Temperature    Precipitation   
 Min.   :2015-01-01   Min.   :16.60   Min.   : 22.00  
 1st Qu.:2015-03-24   1st Qu.:19.82   1st Qu.: 46.88  
 Median :2015-06-16   Median :24.35   Median : 84.00  
 Mean   :2015-06-16   Mean   :23.59   Mean   :118.75  
 3rd Qu.:2015-09-08   3rd Qu.:28.02   3rd Qu.:124.38  
 Max.   :2015-12-01   Max.   :29.00   Max.   :369.00  

To set Temperature 0 – 30 and Precipitation 0 – 400, scale Precipitation by multiplying 30 / 400 to fit range of Temperature

gp1 <- d %>>% ggplot() + 
  geom_bar(mapping = aes(x = Date, y = Precipitation * 30 / 400), stat = "identity") + 
  geom_point(mapping = aes(x = Date, y = Temperature)) + 
  geom_line(mapping = aes(x = Date, y = Temperature)) + 
  scale_y_continuous(name = expression("Temperature ("~degree~"C)"), limits = c(0, 30))
gp1

Scale first Y axis by multiplying 400 / 300 to create secondary Y axis for Precipitation

gp1 <- gp1 %+% scale_y_continuous(name = expression("Temperature ("~degree~"C)"), sec.axis = sec_axis(~ . * 400 / 30 , name = "Precipitation (mm)"), limits = c(0, 30))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
gp1

Final plot

d %>>% ggplot() + 
  geom_bar(mapping = aes(x = Date, y = Precipitation * 30 / 400), stat = "identity", colour = gray(0.5), fill = gray(0.5)) + 
  geom_line(mapping = aes(x = Date, y = Temperature)) + 
  geom_point(mapping = aes(x = Date, y = Temperature), size = 3, shape = 21, fill = "white") + 
  scale_x_date(name = "Month", breaks = seq.Date(as.Date("2015-01-01"), as.Date("2015-12-31"), by = "1 month"), labels = function(date){return(month(date, label = TRUE))}) + 
  scale_y_continuous(
    name = expression("Temperature ("~degree~"C)"), 
    sec.axis = sec_axis(~ . * 400 / 30 , name = "Precipitation (mm)"), 
    limits = c(0, 30)) + 
  theme_bw() + 
  theme(
    panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank()
  )

Complex example: data contains negative values

Temperature and precipitation in Kushiro city, Hokkaido, Japan (2015)

d2 <- read_csv("data/ggplot2-two-axis/kushiro.csv", skip = 5, col_names = c("Date", "Temperature", "Precipitation"), col_types = cols(col_date(format = "%Y/%m"), "d", "_", "_", "d", "_", "_", "_"), locale = locale(encoding = "SJIS"))
head(d2)

Precipitation

d2 %>>% ggplot() + 
  geom_bar(mapping = aes(x = Date, y = Precipitation), stat = "identity") + 
  ylab("Precipitation (mm)")

Temperature

d2 %>>% ggplot() + 
  geom_point(mapping = aes(x = Date, y = Temperature)) + 
  geom_line(mapping = aes(x = Date, y = Temperature)) + 
  ylab(expression("Temperature ("~degree~"C)"))

summary(d2)
      Date             Temperature     Precipitation   
 Min.   :2015-01-01   Min.   :-3.300   Min.   : 37.00  
 1st Qu.:2015-03-24   1st Qu.: 1.300   1st Qu.: 56.00  
 Median :2015-06-16   Median : 7.950   Median : 82.75  
 Mean   :2015-06-16   Mean   : 7.742   Mean   : 96.50  
 3rd Qu.:2015-09-08   3rd Qu.:13.725   3rd Qu.:107.75  
 Max.   :2015-12-01   Max.   :18.400   Max.   :242.00  

To set Temperature -5 – 20 and Precipitation 0 – 250: * Scale Precipitation by multiplying 1/10 to fit range of Temperature, after that, scale Precipitation by adding -5 * Scale first Y axis by adding +5, after that, scale Precipitation by multiplying 10 to create second Y axis for Precipitation

gp2 <- d2 %>>% ggplot() + 
  geom_bar(mapping = aes(x = Date, y = Precipitation / 10 - 5), stat = "identity", colour = gray(0.5), fill = gray(0.5)) + 
  geom_line(mapping = aes(x = Date, y = Temperature)) + 
  geom_point(mapping = aes(x = Date, y = Temperature), size = 3, shape = 21, fill = "white") + 
  scale_x_date(name = "Month", breaks = seq.Date(as.Date("2015-01-01"), as.Date("2015-12-31"), by = "1 month"), labels = function(date){return(month(date, label = TRUE))}) + 
  scale_y_continuous(
    name = expression("Temperature ("~degree~"C)"), 
    sec.axis = sec_axis(~ (. + 5) * 10 , name = "Precipitation (mm)"), 
    limits = c(-5, 20)) + 
  theme_bw() + 
  theme(
    panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank()
  )
gp2

geom_bar() start from 0, use geom_segment()

gp2$layers[[1]] <- geom_segment(mapping = aes(x = Date, y = Precipitation / 10 - 5, xend = Date, yend = -5), size = 11, lineend = "butt", colour = gray(0.5))
gp2

devtools::session_info()
Session info ----------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.2 (2016-10-31)
 system   x86_64, mingw32             
 ui       RStudio (1.0.44)            
 language (EN)                        
 collate  Japanese_Japan.932          
 tz       Asia/Tokyo                  
 date     2016-11-29                  
Packages --------------------------------------------------------------------------------------------------------------
 package    * version date       source        
 assertthat   0.1     2013-12-06 CRAN (R 3.2.1)
 colorspace   1.2-7   2016-10-11 CRAN (R 3.3.2)
 devtools     1.12.0  2016-06-24 CRAN (R 3.3.1)
 digest       0.6.10  2016-08-02 CRAN (R 3.3.1)
 ggplot2    * 2.2.0   2016-11-11 CRAN (R 3.3.2)
 gtable       0.2.0   2016-02-26 CRAN (R 3.2.5)
 knitr        1.15    2016-11-09 CRAN (R 3.3.2)
 labeling     0.3     2014-08-23 CRAN (R 3.2.1)
 lazyeval     0.2.0   2016-06-12 CRAN (R 3.2.5)
 lubridate  * 1.6.0   2016-09-13 CRAN (R 3.2.5)
 magrittr     1.5     2014-11-22 CRAN (R 3.2.1)
 memoise      1.0.0   2016-01-29 CRAN (R 3.2.3)
 munsell      0.4.3   2016-02-13 CRAN (R 3.2.5)
 pipeR      * 0.6.1.3 2016-04-04 CRAN (R 3.3.1)
 plyr         1.8.4   2016-06-08 CRAN (R 3.2.5)
 Rcpp         0.12.7  2016-09-05 CRAN (R 3.2.5)
 readr      * 1.0.0   2016-08-03 CRAN (R 3.2.5)
 scales       0.4.1   2016-11-09 CRAN (R 3.3.2)
 stringi      1.1.2   2016-10-01 CRAN (R 3.3.2)
 stringr      1.1.0   2016-08-19 CRAN (R 3.2.5)
 tibble       1.2     2016-08-26 CRAN (R 3.2.5)
 withr        1.0.2   2016-06-20 CRAN (R 3.2.5)
LS0tDQp0aXRsZTogImdncGxvdDI6IFNlY29uZGFyeSBZIGF4aXMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQotLS0NCg0KKiBFZGl0OiBJbmNyZW1lbnRhbGx5IGNoYW5nZSBleGlzdGluZyBwbG90ICgyMDE2LTExLTI4KQ0KDQotLS0NCg0KVXNlIHBhcmFtZXRlciBgc2VjLmF4aXNgIG9mIGBzY2FsZV95X2NvbnRpbnVvdXMoKWANCg0KIyBTaW1wbGUgZXhhbXBsZQ0KYGBge3J9DQpzYXBwbHkoYygicGlwZVIiLCAiZ2dwbG90MiIsICJyZWFkciIsICJsdWJyaWRhdGUiKSwgcmVxdWlyZSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KYGBgDQpUZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiBpbiBOYWhhIGNpdHksIE9raW5hd2EsIEphcGFuICgyMDE1KQ0KDQoqIE9idGFpbmVkIGZyb20gSmFwYW4gbWV0ZW9yb2xvZ2ljYWwgYWdlbmN5DQpgYGB7cn0NCmQgPC0gcmVhZF9jc3YoImRhdGEvZ2dwbG90Mi10d28tYXhpcy9uYWhhLmNzdiIsIHNraXAgPSA1LCBjb2xfbmFtZXMgPSBjKCJEYXRlIiwgIlRlbXBlcmF0dXJlIiwgIlByZWNpcGl0YXRpb24iKSwgY29sX3R5cGVzID0gY29scyhjb2xfZGF0ZShmb3JtYXQgPSAiJVkvJW0iKSwgImQiLCAiXyIsICJfIiwgImQiLCAiXyIsICJfIiwgIl8iKSwgbG9jYWxlID0gbG9jYWxlKGVuY29kaW5nID0gIlNKSVMiKSkNCmhlYWQoZCkNCmBgYA0KUHJlY2lwaXRhdGlvbg0KYGBge3J9DQpkICU+PiUgZ2dwbG90KCkgKyANCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFByZWNpcGl0YXRpb24pLCBzdGF0ID0gImlkZW50aXR5IikgKyANCiAgeWxhYigiUHJlY2lwaXRhdGlvbiAobW0pIikNCmBgYA0KVGVtcGVyYXR1cmUNCmBgYHtyfQ0KZCAlPj4lIGdncGxvdCgpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFRlbXBlcmF0dXJlKSkgKyANCiAgZ2VvbV9saW5lKG1hcHBpbmcgPSBhZXMoeCA9IERhdGUsIHkgPSBUZW1wZXJhdHVyZSkpICsgDQogIHlsYWIoZXhwcmVzc2lvbigiVGVtcGVyYXR1cmUgKCJ+ZGVncmVlfiJDKSIpKQ0KYGBgDQpSYW5nZSBvZiBkYXRhDQpgYGB7cn0NCnN1bW1hcnkoZCkNCmBgYA0KVG8gc2V0IFRlbXBlcmF0dXJlIDAgLS0gMzAgYW5kIFByZWNpcGl0YXRpb24gMCAtLSA0MDAsIHNjYWxlIFByZWNpcGl0YXRpb24gYnkgbXVsdGlwbHlpbmcgYDMwIC8gNDAwYCB0byBmaXQgcmFuZ2Ugb2YgVGVtcGVyYXR1cmUNCg0KYGBge3J9DQpncDEgPC0gZCAlPj4lIGdncGxvdCgpICsgDQogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IERhdGUsIHkgPSBQcmVjaXBpdGF0aW9uICogMzAgLyA0MDApLCBzdGF0ID0gImlkZW50aXR5IikgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBEYXRlLCB5ID0gVGVtcGVyYXR1cmUpKSArIA0KICBnZW9tX2xpbmUobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFRlbXBlcmF0dXJlKSkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSBleHByZXNzaW9uKCJUZW1wZXJhdHVyZSAoIn5kZWdyZWV+IkMpIiksIGxpbWl0cyA9IGMoMCwgMzApKQ0KZ3AxDQpgYGANCg0KU2NhbGUgZmlyc3QgWSBheGlzIGJ5IG11bHRpcGx5aW5nIGA0MDAgLyAzMDBgIHRvIGNyZWF0ZSBzZWNvbmRhcnkgWSBheGlzIGZvciBQcmVjaXBpdGF0aW9uDQoNCiogYHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAqIDQwMCAvIDMwKSkgYA0KDQpgYGB7cn0NCmdwMSA8LSBncDEgJSslIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gZXhwcmVzc2lvbigiVGVtcGVyYXR1cmUgKCJ+ZGVncmVlfiJDKSIpLCBzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAqIDQwMCAvIDMwICwgbmFtZSA9ICJQcmVjaXBpdGF0aW9uIChtbSkiKSwgbGltaXRzID0gYygwLCAzMCkpDQpncDENCmBgYA0KDQpGaW5hbCBwbG90DQpgYGB7cn0NCmQgJT4+JSBnZ3Bsb3QoKSArIA0KICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBEYXRlLCB5ID0gUHJlY2lwaXRhdGlvbiAqIDMwIC8gNDAwKSwgc3RhdCA9ICJpZGVudGl0eSIsIGNvbG91ciA9IGdyYXkoMC41KSwgZmlsbCA9IGdyYXkoMC41KSkgKyANCiAgZ2VvbV9saW5lKG1hcHBpbmcgPSBhZXMoeCA9IERhdGUsIHkgPSBUZW1wZXJhdHVyZSkpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFRlbXBlcmF0dXJlKSwgc2l6ZSA9IDMsIHNoYXBlID0gMjEsIGZpbGwgPSAid2hpdGUiKSArIA0KICBzY2FsZV94X2RhdGUobmFtZSA9ICJNb250aCIsIGJyZWFrcyA9IHNlcS5EYXRlKGFzLkRhdGUoIjIwMTUtMDEtMDEiKSwgYXMuRGF0ZSgiMjAxNS0xMi0zMSIpLCBieSA9ICIxIG1vbnRoIiksIGxhYmVscyA9IGZ1bmN0aW9uKGRhdGUpe3JldHVybihtb250aChkYXRlLCBsYWJlbCA9IFRSVUUpKX0pICsgDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gZXhwcmVzc2lvbigiVGVtcGVyYXR1cmUgKCJ+ZGVncmVlfiJDKSIpLCANCiAgICBzZWMuYXhpcyA9IHNlY19heGlzKH4gLiAqIDQwMCAvIDMwICwgbmFtZSA9ICJQcmVjaXBpdGF0aW9uIChtbSkiKSwgDQogICAgbGltaXRzID0gYygwLCAzMCkpICsgDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQ0KICApDQpgYGANCg0KIyBDb21wbGV4IGV4YW1wbGU6IGRhdGEgY29udGFpbnMgbmVnYXRpdmUgdmFsdWVzDQpUZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiBpbiBLdXNoaXJvIGNpdHksIEhva2thaWRvLCBKYXBhbiAoMjAxNSkNCg0KKiBPYnRhaW5lZCBmcm9tIEphcGFuIG1ldGVvcm9sb2dpY2FsIGFnZW5jeQ0KDQpgYGB7cn0NCmQyIDwtIHJlYWRfY3N2KCJkYXRhL2dncGxvdDItdHdvLWF4aXMva3VzaGlyby5jc3YiLCBza2lwID0gNSwgY29sX25hbWVzID0gYygiRGF0ZSIsICJUZW1wZXJhdHVyZSIsICJQcmVjaXBpdGF0aW9uIiksIGNvbF90eXBlcyA9IGNvbHMoY29sX2RhdGUoZm9ybWF0ID0gIiVZLyVtIiksICJkIiwgIl8iLCAiXyIsICJkIiwgIl8iLCAiXyIsICJfIiksIGxvY2FsZSA9IGxvY2FsZShlbmNvZGluZyA9ICJTSklTIikpDQpoZWFkKGQyKQ0KYGBgDQpQcmVjaXBpdGF0aW9uDQpgYGB7cn0NCmQyICU+PiUgZ2dwbG90KCkgKyANCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFByZWNpcGl0YXRpb24pLCBzdGF0ID0gImlkZW50aXR5IikgKyANCiAgeWxhYigiUHJlY2lwaXRhdGlvbiAobW0pIikNCmBgYA0KVGVtcGVyYXR1cmUNCmBgYHtyfQ0KZDIgJT4+JSBnZ3Bsb3QoKSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IERhdGUsIHkgPSBUZW1wZXJhdHVyZSkpICsgDQogIGdlb21fbGluZShtYXBwaW5nID0gYWVzKHggPSBEYXRlLCB5ID0gVGVtcGVyYXR1cmUpKSArIA0KICB5bGFiKGV4cHJlc3Npb24oIlRlbXBlcmF0dXJlICgifmRlZ3JlZX4iQykiKSkNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkoZDIpDQpgYGANCg0KVG8gc2V0IFRlbXBlcmF0dXJlIC01IC0tIDIwIGFuZCBQcmVjaXBpdGF0aW9uIDAgLS0gMjUwOiANCiogU2NhbGUgUHJlY2lwaXRhdGlvbiBieSBtdWx0aXBseWluZyBgMS8xMGAgdG8gZml0IHJhbmdlIG9mIFRlbXBlcmF0dXJlLCBhZnRlciB0aGF0LCBzY2FsZSBQcmVjaXBpdGF0aW9uIGJ5IGFkZGluZyBgLTVgDQoqIFNjYWxlIGZpcnN0IFkgYXhpcyBieSBhZGRpbmcgYCs1YCwgYWZ0ZXIgdGhhdCwgc2NhbGUgUHJlY2lwaXRhdGlvbiBieSBtdWx0aXBseWluZyBgMTBgIHRvIGNyZWF0ZSBzZWNvbmQgWSBheGlzIGZvciBQcmVjaXBpdGF0aW9uDQoNCmBgYHtyfQ0KZ3AyIDwtIGQyICU+PiUgZ2dwbG90KCkgKyANCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFByZWNpcGl0YXRpb24gLyAxMCAtIDUpLCBzdGF0ID0gImlkZW50aXR5IiwgY29sb3VyID0gZ3JheSgwLjUpLCBmaWxsID0gZ3JheSgwLjUpKSArIA0KICBnZW9tX2xpbmUobWFwcGluZyA9IGFlcyh4ID0gRGF0ZSwgeSA9IFRlbXBlcmF0dXJlKSkgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBEYXRlLCB5ID0gVGVtcGVyYXR1cmUpLCBzaXplID0gMywgc2hhcGUgPSAyMSwgZmlsbCA9ICJ3aGl0ZSIpICsgDQogIHNjYWxlX3hfZGF0ZShuYW1lID0gIk1vbnRoIiwgYnJlYWtzID0gc2VxLkRhdGUoYXMuRGF0ZSgiMjAxNS0wMS0wMSIpLCBhcy5EYXRlKCIyMDE1LTEyLTMxIiksIGJ5ID0gIjEgbW9udGgiKSwgbGFiZWxzID0gZnVuY3Rpb24oZGF0ZSl7cmV0dXJuKG1vbnRoKGRhdGUsIGxhYmVsID0gVFJVRSkpfSkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSBleHByZXNzaW9uKCJUZW1wZXJhdHVyZSAoIn5kZWdyZWV+IkMpIiksIA0KICAgIHNlYy5heGlzID0gc2VjX2F4aXMofiAoLiArIDUpICogMTAgLCBuYW1lID0gIlByZWNpcGl0YXRpb24gKG1tKSIpLCANCiAgICBsaW1pdHMgPSBjKC01LCAyMCkpICsgDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQ0KICApDQpncDINCmBgYA0KDQpgZ2VvbV9iYXIoKWAgc3RhcnQgZnJvbSBgMGAsIHVzZSBgZ2VvbV9zZWdtZW50KClgDQoNCmBgYHtyfQ0KZ3AyJGxheWVyc1tbMV1dIDwtIGdlb21fc2VnbWVudChtYXBwaW5nID0gYWVzKHggPSBEYXRlLCB5ID0gUHJlY2lwaXRhdGlvbiAvIDEwIC0gNSwgeGVuZCA9IERhdGUsIHllbmQgPSAtNSksIHNpemUgPSAxMSwgbGluZWVuZCA9ICJidXR0IiwgY29sb3VyID0gZ3JheSgwLjUpKQ0KZ3AyDQpgYGANCg0KYGBge3J9DQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKCkNCmBgYA==