How to plot y1 and y2 axis with different values in r

Hi, I would like to plot a ts line graph showing maximum and minimum temperature on y1 axis and rainfall on y2 axis. I tried to load the csv file and convert date value but it still returns a character. Some help with this please. Here is my script:

library(ggplot2)
library(lubridate)
setwd("D:/R_scrips")
data<-read.csv("D:/R_scrips/temp_rain.csv", header=T, stringsAsFactors = FALSE)
head(data)
date max_temp min_temp rainfall
1 Jan-80 33.1 19.4 45
2 Feb-80 33.0 19.8 67
3 Mar-80 31.5 19.2 209
4 Apr-80 30.6 19.1 180
5 May-80 28.9 18.7 131
6 Jun-80 28.8 18.4 115
as.Date(data$date,format="%d-%b-%y")
[1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
str(data)
'data.frame': 24 obs. of 4 variables:
date : chr "Jan-80" "Feb-80" "Mar-80" "Apr-80" ... max_temp: num 33.1 33 31.5 30.6 28.9 28.8 27.9 29.2 30.9 30.6 ...
min_temp: num 19.4 19.8 19.2 19.1 18.7 18.4 17.6 17.7 17.9 18.2 ... rainfall: int 45 67 209 180 131 115 104 184 133 121 ...
data
date max_temp min_temp rainfall
1 Jan-80 33.1 19.4 45
2 Feb-80 33.0 19.8 67
3 Mar-80 31.5 19.2 209
4 Apr-80 30.6 19.1 180
5 May-80 28.9 18.7 131
6 Jun-80 28.8 18.4 115
7 Jul-80 27.9 17.6 104
8 Aug-80 29.2 17.7 184
9 Sep-80 30.9 17.9 133
10 Oct-80 30.6 18.2 121
11 Nov-80 29.8 17.9 80
12 Dec-80 31.5 18.6 36
13 Jan-81 33.4 18.3 43
14 Feb-81 34.4 17.7 38
15 Mar-81 29.6 17.8 101
16 Apr-81 28.5 19.4 193
17 May-81 28.7 18.0 208
18 Jun-81 29.3 17.6 79
19 Jul-81 28.1 17.8 81
20 Aug-81 27.9 17.8 94
21 Sep-81 29.6 17.6 109
22 Oct-81 30.5 18.0 189
23 Nov-81 30.1 17.9 156
24 Dec-81 31.7 18.2 35

The date conversion is failing because there is no day information, just the month and the year. Below is a procedure for appending a day and then converting to a numeric date.

library(lubridate)
library(dplyr)
Data <- read.table("/home/fjcc/R/Play/Rainfall.dat", sep = " ", 
                   header = TRUE, stringsAsFactors = FALSE)
head(Data)
#>     date max_temp min_temp rainfall
#> 1 Jan-80     33.1     19.4       45
#> 2 Feb-80     33.0     19.8       67
#> 3 Mar-80     31.5     19.2      209
#> 4 Apr-80     30.6     19.1      180
#> 5 May-80     28.9     18.7      131
#> 6 Jun-80     28.8     18.4      115
Data <- Data %>% mutate(date = paste0("01-", date))
head(Data)
#>        date max_temp min_temp rainfall
#> 1 01-Jan-80     33.1     19.4       45
#> 2 01-Feb-80     33.0     19.8       67
#> 3 01-Mar-80     31.5     19.2      209
#> 4 01-Apr-80     30.6     19.1      180
#> 5 01-May-80     28.9     18.7      131
#> 6 01-Jun-80     28.8     18.4      115
Data <- Data %>% mutate(date = dmy(date))
summary(Data)
#>       date               max_temp        min_temp        rainfall    
#>  Min.   :1980-01-01   Min.   :27.90   Min.   :17.60   Min.   : 35.0  
#>  1st Qu.:1980-06-23   1st Qu.:28.88   1st Qu.:17.80   1st Qu.: 76.0  
#>  Median :1980-12-16   Median :29.95   Median :18.00   Median :106.5  
#>  Mean   :1980-12-15   Mean   :30.32   Mean   :18.27   Mean   :113.8  
#>  3rd Qu.:1981-06-08   3rd Qu.:31.50   3rd Qu.:18.62   3rd Qu.:162.0  
#>  Max.   :1981-12-01   Max.   :34.40   Max.   :19.80   Max.   :209.0

Created on 2019-04-30 by the reprex package (v0.2.1)

Thanks FJCC, for the help, I have put in the commands but it returned an error message as below:

library(lubridate)
library(dplyr)
Data<-read.csv("D:/R_scrips/temp_rain.csv", sep = " ", header=T, stringsAsFactors = FALSE)
head(Data)
date.max_temp.min_temp.rainfall
1 Jan-80,33.1,19.4,45
2 Feb-80,33,19.8,67
3 Mar-80,31.5,19.2,209
4 Apr-80,30.6,19.1,180
5 May-80,28.9,18.7,131
6 Jun-80,28.8,18.4,115
Data <- Data %>% mutate(date = paste0("01-", date))
Error in paste0("01-", date) :
cannot coerce type 'closure' to vector of type 'character'
I would like some support on how to generate the graph as well. Thanks

The structure of your data frame seems incorrect. It looks like you have a single column with the column name date.max_temp.min_temp.rainfall. Try setting the separator character in read.csv to be a comma.

Data <- read.csv("D:/R_scrips/temp_rain.csv", sep = ",", header=T, stringsAsFactors = FALSE)

You can use ggplot2::sec_axis() but the secondary axis has to be based on a one-to-one transformation of the primary axis.

Data <- data.frame(stringsAsFactors = FALSE,
                   max_temp = c(33.1, 33, 31.5, 30.6, 28.9, 28.8, 27.9, 29.2, 30.9, 30.6,
                                29.8, 31.5, 33.4, 34.4, 29.6, 28.5, 28.7, 29.3, 28.1, 27.9,
                                29.6, 30.5, 30.1, 31.7),
                   min_temp = c(19.4, 19.8, 19.2, 19.1, 18.7, 18.4, 17.6, 17.7, 17.9, 18.2,
                                17.9, 18.6, 18.3, 17.7, 17.8, 19.4, 18, 17.6, 17.8, 17.8,
                                17.6, 18, 17.9, 18.2),
                   rainfall = c(45L, 67L, 209L, 180L, 131L, 115L, 104L, 184L, 133L, 121L, 80L,
                                36L, 43L, 38L, 101L, 193L, 208L, 79L, 81L, 94L, 109L, 189L,
                                156L, 35L),
                   date = c("Jan-80", "Feb-80", "Mar-80", "Apr-80", "May-80",
                            "Jun-80", "Jul-80", "Aug-80", "Sep-80", "Oct-80",
                            "Nov-80", "Dec-80", "Jan-81", "Feb-81", "Mar-81",
                            "Apr-81", "May-81", "Jun-81", "Jul-81", "Aug-81", "Sep-81",
                            "Oct-81", "Nov-81", "Dec-81"))
library(tidyverse)
library(lubridate)

Data %>%
    mutate(date = dmy(paste("01-", date)), rainfall =  rainfall / 5) %>% 
    gather(variable, temp, -date) %>%
    ggplot(aes(x = date, y = temp, color = variable)) +
    geom_line() +
    scale_x_date(date_labels = "%b-%y",
                 date_breaks = "1 month",
                 minor_breaks = "1 month",
                 expand = c(0,0)) +
    scale_y_continuous(sec.axis = sec_axis(~ . * 5, name = "Rainfall")) +
    theme_minimal() +
    theme(axis.text.x = element_text(angle=45, hjust=1, vjust = 1))

Thank You so much Andres for your great help. The graph has come out perfectly well.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.