Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write_csv() returns modified tibble instead of input #975

Closed
adamroyjones opened this issue Mar 5, 2019 · 6 comments · Fixed by #1047
Closed

write_csv() returns modified tibble instead of input #975

adamroyjones opened this issue Mar 5, 2019 · 6 comments · Fixed by #1047

Comments

@adamroyjones
Copy link
Contributor

The subject describes the issue fully. Below is a working example. Versions are:

  • R 3.5.2 (on Ubuntu 16.04.5 LTS on x86_64),
  • readr 1.3.1,
  • magrittr 1.5,
  • lubridate 1.7.4, and
  • tibble 2.0.1.
library(tibble)
library(lubridate)
library(magrittr)
library(readr)

tbl = tribble(
  ~date, ~value,
  ymd("2019-05-05"), 1
)

tbl # class(tbl$date[1]) = "Date"

tbl = tbl %>% write_csv("tmp.csv")

tbl # class(tbl$date[1]) = "character"
@cderv
Copy link
Contributor

cderv commented Mar 5, 2019

This comes from here

readr/R/write.R

Lines 62 to 71 in 271bb3f

write_delim <- function(x, path, delim = " ", na = "NA", append = FALSE,
col_names = !append, quote_escape = "double") {
stopifnot(is.data.frame(x))
x[] <- lapply(x, output_column)
stream_delim(x, path, delim = delim, col_names = col_names, append = append,
na = na, quote_escape = quote_escape)
invisible(x)
}

line 66: x is modified to be prepared for writing as text ouput in a text file. And the function will return this modified object instead of the original one. Converting date (and other types) to character is one of the change.

However, the documentation says

write_*() returns the input x invisibly.

So, this seems like a bug or a documentation with not enough precision 🤔

@gadenbuie
Copy link

gadenbuie commented Mar 22, 2019

This was not the behavior of write_csv() in earlier versions of readr. I'm not sure of the version where this bug was introduced, but I tested on version 1.1.1 before upgrading to version 1.3.1, and the input was returned intact.

Here's a more complete reprex showing that this also applies to factors that are converted to characters for writing to csv.

library(tidyverse)
library(lubridate)

x <- tibble(
  x = factor(letters[1:4]),
  y = now(tz = "America/New_York") - days(0:3)
)

y <- write_csv(x, "tmp.csv")

identical(x, y)
#> [1] FALSE

x
#> # A tibble: 4 x 2
#>   x     y                  
#>   <fct> <dttm>             
#> 1 a     2019-03-21 21:56:29
#> 2 b     2019-03-20 21:56:29
#> 3 c     2019-03-19 21:56:29
#> 4 d     2019-03-18 21:56:29
y
#> # A tibble: 4 x 2
#>   x     y                   
#>   <chr> <chr>               
#> 1 a     2019-03-22T01:56:29Z
#> 2 b     2019-03-21T01:56:29Z
#> 3 c     2019-03-20T01:56:29Z
#> 4 d     2019-03-19T01:56:29Z
read_csv("tmp.csv")
#> # A tibble: 4 x 2
#>   x     y                  
#>   <chr> <dttm>             
#> 1 a     2019-03-22 01:56:29
#> 2 b     2019-03-21 01:56:29
#> 3 c     2019-03-20 01:56:29
#> 4 d     2019-03-19 01:56:29

Created on 2019-03-22 by the reprex package (v0.2.1)

Session info
devtools::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.5.1 (2018-07-02)
#>  os       Ubuntu 18.04.1 LTS          
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  C.UTF-8                     
#>  ctype    C.UTF-8                     
#>  tz       Etc/UTC                     
#>  date     2019-03-22                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version    date       lib source                        
#>  assertthat    0.2.1      2019-03-21 [1] standard (@0.2.1)             
#>  backports     1.1.3      2018-12-14 [1] CRAN (R 3.5.1)                
#>  broom         0.5.0      2018-07-17 [2] CRAN (R 3.5.1)                
#>  callr         3.1.1      2018-12-21 [1] CRAN (R 3.5.1)                
#>  cellranger    1.1.0      2016-07-27 [2] CRAN (R 3.5.1)                
#>  cli           1.1.0      2019-03-19 [1] standard (@1.1.0)             
#>  colorspace    1.4-0      2019-01-13 [1] standard (@1.4-0)             
#>  crayon        1.3.4      2017-09-16 [1] standard (@1.3.4)             
#>  desc          1.2.0      2018-05-01 [2] CRAN (R 3.5.1)                
#>  devtools      2.0.1      2018-10-26 [2] CRAN (R 3.5.1)                
#>  digest        0.6.18     2018-10-10 [1] standard (@0.6.18)            
#>  dplyr       * 0.8.0.1    2019-02-15 [1] standard (@0.8.0.1)           
#>  evaluate      0.13       2019-02-12 [1] standard (@0.13)              
#>  fansi         0.4.0      2018-10-05 [1] standard (@0.4.0)             
#>  forcats     * 0.3.0      2018-02-19 [2] CRAN (R 3.5.1)                
#>  fs            1.2.6      2018-08-23 [2] CRAN (R 3.5.1)                
#>  ggplot2     * 3.1.0      2018-10-25 [1] standard (@3.1.0)             
#>  glue          1.3.0      2018-07-17 [1] standard (@1.3.0)             
#>  gtable        0.2.0      2016-02-26 [1] standard (@0.2.0)             
#>  haven         2.0.0      2018-11-22 [1] CRAN (R 3.5.1)                
#>  highr         0.7        2018-06-09 [1] standard (@0.7)               
#>  hms           0.4.2      2018-03-10 [1] standard (@0.4.2)             
#>  htmltools     0.3.6      2017-04-28 [1] CRAN (R 3.5.1)                
#>  httr          1.4.0      2018-12-11 [1] CRAN (R 3.5.1)                
#>  jsonlite      1.6        2018-12-07 [1] CRAN (R 3.5.1)                
#>  knitr         1.22       2019-03-08 [1] CRAN (R 3.5.1)                
#>  lattice       0.20-38    2018-11-04 [1] standard (@0.20-38)           
#>  lazyeval      0.2.1      2017-10-29 [1] standard (@0.2.1)             
#>  lubridate   * 1.7.4      2018-04-11 [2] CRAN (R 3.5.1)                
#>  magrittr      1.5        2014-11-22 [1] standard (@1.5)               
#>  memoise       1.1.0      2017-04-21 [2] CRAN (R 3.5.1)                
#>  modelr        0.1.2      2018-05-11 [2] CRAN (R 3.5.1)                
#>  munsell       0.5.0      2018-06-12 [1] standard (@0.5.0)             
#>  nlme          3.1-137    2018-04-07 [1] standard (@3.1-137)           
#>  pillar        1.3.1      2018-12-15 [1] CRAN (R 3.5.1)                
#>  pkgbuild      1.0.2      2018-10-16 [2] CRAN (R 3.5.1)                
#>  pkgconfig     2.0.2      2018-08-16 [1] standard (@2.0.2)             
#>  pkgload       1.0.2      2018-10-29 [2] CRAN (R 3.5.1)                
#>  plyr          1.8.4      2016-06-08 [1] standard (@1.8.4)             
#>  prettyunits   1.0.2      2015-07-13 [2] CRAN (R 3.5.1)                
#>  processx      3.2.1      2018-12-05 [1] CRAN (R 3.5.1)                
#>  ps            1.3.0      2018-12-21 [1] CRAN (R 3.5.1)                
#>  purrr       * 0.3.1      2019-03-03 [1] standard (@0.3.1)             
#>  R6            2.4.0      2019-02-14 [1] CRAN (R 3.5.1)                
#>  Rcpp          1.0.1      2019-03-17 [1] standard (@1.0.1)             
#>  readr       * 1.3.1      2018-12-21 [1] standard (@1.3.1)             
#>  readxl        1.1.0      2018-04-20 [2] CRAN (R 3.5.1)                
#>  remotes       2.0.2      2018-10-30 [2] CRAN (R 3.5.1)                
#>  rlang         0.3.2      2019-03-21 [1] standard (@0.3.2)             
#>  rmarkdown     1.11       2018-12-08 [1] CRAN (R 3.5.1)                
#>  rprojroot     1.3-2      2018-01-03 [1] standard (@1.3-2)             
#>  rvest         0.3.2      2016-06-17 [2] CRAN (R 3.5.1)                
#>  scales        1.0.0      2018-08-09 [1] standard (@1.0.0)             
#>  sessioninfo   1.1.1      2018-11-05 [2] CRAN (R 3.5.1)                
#>  stringi       1.4.3      2019-03-12 [1] CRAN (R 3.5.1)                
#>  stringr     * 1.4.0      2019-02-10 [1] CRAN (R 3.5.1)                
#>  testthat      2.0.1      2018-10-13 [1] CRAN (R 3.5.1)                
#>  tibble      * 2.1.1      2019-03-16 [1] standard (@2.1.1)             
#>  tidyr       * 0.8.3      2019-03-01 [1] standard (@0.8.3)             
#>  tidyselect    0.2.5      2018-10-11 [1] standard (@0.2.5)             
#>  tidyverse   * 1.2.1      2017-11-14 [2] CRAN (R 3.5.1)                
#>  usethis       1.4.0.9000 2018-12-26 [1] Github (r-lib/usethis@85bf30a)
#>  utf8          1.1.4      2018-05-24 [1] standard (@1.1.4)             
#>  withr         2.1.2      2018-03-15 [1] standard (@2.1.2)             
#>  xfun          0.5        2019-02-20 [1] standard (@0.5)               
#>  xml2          1.2.0      2018-01-24 [2] CRAN (R 3.5.1)                
#>  yaml          2.2.0      2018-07-25 [1] CRAN (R 3.5.1)                
#> 
#> [1] /home/garrick/R/x86_64-pc-linux-gnu-library/3.5
#> [2] /usr/local/lib/R/site-library
#> [3] /usr/lib/R/site-library
#> [4] /usr/lib/R/library

@gadenbuie
Copy link

May I suggest renaming this issue to "write_csv() returns modified tibble instead of input" (or something similar)?

Also, write_delim() previously distinguished between the input and modified output tables.

readr/R/write.R

Lines 62 to 71 in ddbb5f4

write_delim <- function(x, path, delim = " ", na = "NA", append = FALSE,
col_names = !append) {
stopifnot(is.data.frame(x))
x_out <- lapply(x, output_column)
stream_delim(x_out, path, delim, col_names = col_names, append = append,
na = na)
invisible(x)
}

@cderv
Copy link
Contributor

cderv commented Mar 23, 2019

For reference, the change were x_out was removed happened here ba7edb5 in a commit to fix a bug regarding datetime conversion

@adamroyjones adamroyjones changed the title "Date" columns in a tibble are (sometimes?) converted to "character" upon calling write_csv write_csv() returns modified tibble instead of input Apr 7, 2019
@adamroyjones
Copy link
Contributor Author

@gadenbuie: You're quite right—it's a better subject. I've made the change.

@lock
Copy link

lock bot commented May 20, 2020

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants