write_clean_csv() writes a data frame to a CSV file using
readr::write_csv() and emits a cli confirmation message reporting
the number of rows and columns written. It is the natural counterpart
to read_clean_csv(), reinforcing the convention that data-raw/
holds original inputs and data/ holds cleaned, analysis-ready outputs.
Arguments
- data
A data frame or tibble to write.
- path
A character string with the path to the output CSV file. A relative path is written under the project root (see the Paths section), and its folder is created if it does not exist.
- overwrite
Logical. If
FALSE(the default), errors if the file already exists. Set toTRUEto overwrite an existing file.- ...
Additional arguments passed to
readr::write_csv(), such asappend,col_names, orquote.
Details
If column names are not already clean, write_clean_csv() applies
janitor::clean_names() before writing and emits a warning listing
the affected columns.
Paths
A relative path is read from the project root, not from the working
directory. So save_output(fit, "output/fit.rds", saveRDS) writes into
the project's own output/ folder whether you call it from the project
root, from a document under reports/, or from a job on an HTCondor
execute node. You never need to wrap a path in here::here(). Doing so
still works, because here::here() returns an absolute path and
absolute paths are used as given.
The project root is found afresh on every call, in this order:
The job's scratch directory, when
_CONDOR_SCRATCH_DIRnames one. HTCondor sets that variable itself, inside every job.The nearest folder above the working directory that carries a project marker: the
.herefileinit_project()writes, an.Rprojfile, a packageDESCRIPTION, or a version control folder such as.git.The working directory, when neither of the above applies.
Absolute paths (including those starting with ~, or a drive letter
on Windows) and URLs such as https:// or s3:// are used as given.
.. and ./ are not interpreted, so "../data/x.csv" means the folder
above the root; write an absolute path to leave the project. A bare
"." means the root itself.
Functions that read are forgiving about older code. A relative path that does not exist at the project root but does exist relative to the working directory is read from there, and a message says so. Functions that write never guess: a relative path is always written under the root.
A few arguments are deliberately left alone:
init_project()readspath,configanduse_rprofilefrom the working directory, because the project does not exist yet and so has no root.Under
Rscript,resolve_input_path()reads the command line argument as given. RunRscriptfrom the project root or pass an absolute path.Arguments passed on through
...to another function reach it untouched.Where a default is "beside the input" (
qmd_to_r()andgenerate_kb_xml()), the output follows wherever the input was read from.
Two limits are worth knowing. A project nested inside another project is
not supported: the nearest marker wins, which can surprise you when you
work from the outer one. And on an execute node ~ and $HOME cannot
be trusted ($HOME can be the submit node's path), so prefer relative
paths in job scripts.
Examples
# \donttest{
sample_path <- system.file("templates", "sample.csv", package = "toolero")
data <- read_clean_csv(sample_path)
# Write to a temp file
out <- tempfile(fileext = ".csv")
write_clean_csv(data, out)
#> ✔ Wrote 344 rows and 8 columns to /tmp/RtmpVdwYt8/file1a89582606d5.csv.
# Overwrite an existing file
write_clean_csv(data, out, overwrite = TRUE)
#> ✔ Wrote 344 rows and 8 columns to /tmp/RtmpVdwYt8/file1a89582606d5.csv.
# Dirty names are cleaned automatically with a warning
dirty <- data.frame("First Name" = "Jane", "Last Name" = "Doe",
check.names = FALSE)
write_clean_csv(dirty, tempfile(fileext = ".csv"))
#> Warning: Column names were not clean -- applying `janitor::clean_names()` before
#> writing. Affected columns: "First Name" and "Last Name"
#> ✔ Wrote 1 row and 2 columns to /tmp/RtmpVdwYt8/file1a894eb6b11.csv.
# }
