Search code examples
rcsviso8601readr

How can I save Time data to csv file using write_csv without T or Z character?


I'm trying to save some time information included data with write_csv.

But it keeps showing T and Z character (ISO8601 format as I know).

For example, 2022-12-12 08:00:00 is shown as 2022-12-12T08:00:00Z on csv file open with notepad.

I want keep original data format after saving csv file, but I couldnt find option for this.

Just saw a article about this problem but there is no answer.

Other Q


Solution

  • Here are two solutions.

    First write a data set to a temp file.

    library(readr)
    
    df1 <- data.frame(datetime = as.POSIXct("2022-12-12 08:00:00"),
                      x = 1L, y = 2)
    csvfile <- tempfile(fileext = ".csv")
    
    # write the data, this is the problem instruction
    write_csv(df1, file = csvfile)
    

    Created on 2023-01-31 with reprex v2.0.2

    1. Change nothing

    This is probably not what you want but read_csv recognizes write_csv's ISO8601 output format, so if the data is written to file with write_csv and read in from disk with read_csv the problem doesn't occur.

    # read from file as text, problem format is present
    readLines(csvfile)
    #> [1] "datetime,x,y"             "2022-12-12T08:00:00Z,1,2"
    
    # read from file as spec_tbl_df, problem format is not present
    read_csv(csvfile, show_col_types = FALSE)
    #> # A tibble: 1 × 3
    #>   datetime                x     y
    #>   <dttm>              <dbl> <dbl>
    #> 1 2022-12-12 08:00:00     1     2
    

    Created on 2023-01-31 with reprex v2.0.2

    2. Coerce to "character"

    If the datetime column of class "POSIXct" is coerced to character the ISO8601 format is gone and everything is OK. And afterwards read_csv will recognize the datetime column.
    This is done in a pipe, below with the base pipe operator introduced in R 4.1, in order not to change the original data.

    # coerce the problem column to character and write to file
    # done in a pipe it won't alter the original data set
    df1 |>
      dplyr::mutate(datetime = as.character(datetime)) |>
      write_csv(file = csvfile)
    
    # check result, both are OK
    readLines(csvfile)
    #> [1] "datetime,x,y"            "2022-12-12 08:00:00,1,2"
    
    read_csv(csvfile, show_col_types = FALSE)
    #> # A tibble: 1 × 3
    #>   datetime                x     y
    #>   <dttm>              <dbl> <dbl>
    #> 1 2022-12-12 08:00:00     1     2
    

    Created on 2023-01-31 with reprex v2.0.2

    Final clean up.

    unlink(csvfile)