rio/0000755000176200001440000000000014502301742011041 5ustar liggesusersrio/NAMESPACE0000644000176200001440000000455614500613454012276 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(.export,rio_arff) S3method(.export,rio_clipboard) S3method(.export,rio_csv) S3method(.export,rio_csv2) S3method(.export,rio_csvy) S3method(.export,rio_dbf) S3method(.export,rio_dta) S3method(.export,rio_dump) S3method(.export,rio_feather) S3method(.export,rio_fods) S3method(.export,rio_fst) S3method(.export,rio_fwf) S3method(.export,rio_html) S3method(.export,rio_json) S3method(.export,rio_matlab) S3method(.export,rio_ods) S3method(.export,rio_parquet) S3method(.export,rio_psv) S3method(.export,rio_pzfx) S3method(.export,rio_qs) S3method(.export,rio_r) S3method(.export,rio_rda) S3method(.export,rio_rdata) S3method(.export,rio_rds) S3method(.export,rio_sas7bdat) S3method(.export,rio_sav) S3method(.export,rio_tsv) S3method(.export,rio_txt) S3method(.export,rio_xlsx) S3method(.export,rio_xml) S3method(.export,rio_xpt) S3method(.export,rio_yml) S3method(.export,rio_zsav) S3method(.import,rio_arff) S3method(.import,rio_clipboard) S3method(.import,rio_csv) S3method(.import,rio_csv2) S3method(.import,rio_csvy) S3method(.import,rio_dat) S3method(.import,rio_dbf) S3method(.import,rio_dif) S3method(.import,rio_dta) S3method(.import,rio_dump) S3method(.import,rio_eviews) S3method(.import,rio_feather) S3method(.import,rio_fods) S3method(.import,rio_fortran) S3method(.import,rio_fst) S3method(.import,rio_fwf) S3method(.import,rio_html) S3method(.import,rio_json) S3method(.import,rio_matlab) S3method(.import,rio_mtp) S3method(.import,rio_ods) S3method(.import,rio_parquet) S3method(.import,rio_psv) S3method(.import,rio_pzfx) S3method(.import,rio_qs) S3method(.import,rio_r) S3method(.import,rio_rda) S3method(.import,rio_rdata) S3method(.import,rio_rds) S3method(.import,rio_rec) S3method(.import,rio_sas7bdat) S3method(.import,rio_sav) S3method(.import,rio_spss) S3method(.import,rio_syd) S3method(.import,rio_tsv) S3method(.import,rio_txt) S3method(.import,rio_xls) S3method(.import,rio_xlsx) S3method(.import,rio_xml) S3method(.import,rio_xpt) S3method(.import,rio_yml) S3method(.import,rio_zsav) S3method(characterize,data.frame) S3method(characterize,default) S3method(factorize,data.frame) S3method(factorize,default) export(characterize) export(convert) export(export) export(export_list) export(factorize) export(gather_attrs) export(get_ext) export(get_info) export(import) export(import_list) export(install_formats) export(spread_attrs) rio/README.md0000644000176200001440000003162714502270161012331 0ustar liggesusers # rio: A Swiss-Army Knife for Data I/O [![CRAN Version](https://www.r-pkg.org/badges/version/rio)](https://cran.r-project.org/package=rio) ![Downloads](https://cranlogs.r-pkg.org/badges/rio) ## Overview The aim of **rio** is to make data file I/O in R as easy as possible by implementing two main functions in Swiss-army knife style: - `import()` provides a painless data import experience by automatically choosing the appropriate import/read function based on file extension (or a specified `format` argument) - `export()` provides the same painless file recognition for data export/write functionality ## Installation The package is available on [CRAN](https://cran.r-project.org/package=rio) and can be installed directly in R using `install.packages()`. ``` r install.packages("rio") ``` The latest development version on GitHub can be installed using: ``` r if (!require("remotes")){ install.packages("remotes") } remotes::install_github("gesistsa/rio") ``` Optional: Installation of additional formats (see below: **Supported file formats**) ``` r library(rio) install_formats() ``` ## Usage Because **rio** is meant to streamline data I/O, the package is extremely easy to use. Here are some examples of reading, writing, and converting data files. ### Import Importing data is handled with one function, `import()`: ``` r library("rio") import("starwars.xlsx") ``` ## Name homeworld species ## 1 Luke Skywalker Tatooine Human ## 2 C-3PO Tatooine Human ## 3 R2-D2 Alderaan Human ## 4 Darth Vader Tatooine Human ## 5 Leia Organa Tatooine Human ## 6 Owen Lars Tatooine Human ## 7 Beru Whitesun lars Stewjon Human ## 8 R5-D4 Tatooine Human ## 9 Biggs Darklighter Kashyyyk Wookiee ## 10 Obi-Wan Kenobi Corellia Human ``` r import("starwars.csv") ``` ## Name homeworld species ## 1 Luke Skywalker Tatooine Human ## 2 C-3PO Tatooine Human ## 3 R2-D2 Alderaan Human ## 4 Darth Vader Tatooine Human ## 5 Leia Organa Tatooine Human ## 6 Owen Lars Tatooine Human ## 7 Beru Whitesun lars Stewjon Human ## 8 R5-D4 Tatooine Human ## 9 Biggs Darklighter Kashyyyk Wookiee ## 10 Obi-Wan Kenobi Corellia Human Note: Because of inconsistencies across underlying packages, the data.frame returned by `import` might vary slightly (in variable classes and attributes) depending on file type. ### Export Exporting data is handled with one function, `export()`: ``` r export(mtcars, "mtcars.csv") # comma-separated values export(mtcars, "mtcars.rds") # R serialized export(mtcars, "mtcars.sav") # SPSS ``` A particularly useful feature of rio is the ability to import from and export to compressed (e.g., zip) directories, saving users the extra step of compressing a large exported file, e.g.: ``` r export(mtcars, "mtcars.tsv.zip") ``` `export()` can also write multiple data frames to respective sheets of an Excel workbook or an HTML file: ``` r export(list(mtcars = mtcars, iris = iris), file = "mtcars.xlsx") ``` ## Supported file formats **rio** supports a wide range of file formats. To keep the package slim, several formats are supported via “Suggests” packages, which are not installed (or loaded) by default. To ensure rio is fully functional, install these packages the first time you use **rio** via: ``` r install_formats() ``` The full list of supported formats is below: | Name | Extensions / “format” | Import Package | Export Package | Type | Note | | :---------------------------------- | :-------------------- | :------------- | :------------- | :------ | :---------------------- | | Archive files (handled by tar) | bzip2 / xz / tar | utils | utils | Default | | | Gzip files | gz / gzip | base | base | Default | | | Zip files | zip | utils | utils | Default | | | CSVY (CSV + YAML metadata header) | csvy | data.table | data.table | Default | | | Comma-separated data | csv | data.table | data.table | Default | | | Comma-separated data (European) | csv2 | data.table | data.table | Default | | | Data Interchange Format | dif | utils | | Default | | | Epiinfo | epiinfo / rec | foreign | | Default | | | Excel | excel / xlsx | readxl | writexl | Default | | | Excel (Legacy) | xls | readxl | | Default | | | Fixed-width format data | fwf | utils | utils | Default | | | Fortran data | fortran | utils | | Default | No recognized extension | | Google Sheets | googlesheets | data.table | | Default | As comma-separated data | | Minitab | minitab / mtp | foreign | | Default | | | Pipe-separated data | psv | data.table | data.table | Default | | | R syntax | r | base | base | Default | | | SAS | sas / sas7bdat | haven | haven | Default | Export is deprecated | | SAS XPORT | xport / xpt | haven | haven | Default | | | SPSS | sav / spss | haven | haven | Default | | | SPSS (compressed) | zsav | haven | haven | Default | | | SPSS Portable | por | haven | | Default | | | Saved R objects | rda / rdata | base | base | Default | | | Serialized R objects | rds | base | base | Default | | | Stata | dta / stata | haven | haven | Default | | | Systat | syd / systat | foreign | | Default | | | Tab-separated data | / tsv / txt | data.table | data.table | Default | | | Text Representations of R Objects | dump | base | base | Default | | | Weka Attribute-Relation File Format | arff / weka | foreign | foreign | Default | | | XBASE database files | dbf | foreign | foreign | Default | | | Apache Arrow (Parquet) | parquet | arrow | arrow | Suggest | | | Clipboard | clipboard | clipr | clipr | Suggest | default is tsv | | EViews | eviews / wf1 | hexView | | Suggest | | | Fast Storage | fst | fst | fst | Suggest | | | Feather R/Python interchange format | feather | arrow | arrow | Suggest | | | Graphpad Prism | pzfx | pzfx | pzfx | Suggest | | | HTML Tables | htm / html | xml2 | xml2 | Suggest | | | JSON | json | jsonlite | jsonlite | Suggest | | | Matlab | mat / matlab | rmatio | rmatio | Suggest | | | OpenDocument Spreadsheet | ods | readODS | readODS | Suggest | | | OpenDocument Spreadsheet (Flat) | fods | readODS | readODS | Suggest | | | Serialized R objects (Quick) | qs | qs | qs | Suggest | | | Shallow XML documents | xml | xml2 | xml2 | Suggest | | | YAML | yaml / yml | yaml | yaml | Suggest | | Additionally, any format that is not supported by **rio** but that has a known R implementation will produce an informative error message pointing to a package and import or export function. Unrecognized formats will yield a simple “Unrecognized file format” error. ## Other functions ### Convert The `convert()` function links `import()` and `export()` by constructing a dataframe from the imported file and immediately writing it back to disk. `convert()` invisibly returns the file name of the exported file, so that it can be used to programmatically access the new file. ``` r convert("mtcars.sav", "mtcars.dta") ``` It is also possible to use **rio** on the command-line by calling `Rscript` with the `-e` (expression) argument. For example, to convert a file from Stata (.dta) to comma-separated values (.csv), simply do the following: Rscript -e "rio::convert('iris.dta', 'iris.csv')" ### \*\_list `import_list()` allows users to import a list of data frames from a multi-object file (such as an Excel workbook, .Rdata file, zip directory, or HTML file): ``` r str(m <- import_list("mtcars.xlsx")) ``` ## List of 2 ## $ mtcars:'data.frame': 32 obs. of 11 variables: ## ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... ## ..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ... ## ..$ disp: num [1:32] 160 160 108 258 360 ... ## ..$ hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ... ## ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... ## ..$ wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ... ## ..$ qsec: num [1:32] 16.5 17 18.6 19.4 17 ... ## ..$ vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ... ## ..$ am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ... ## ..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ... ## ..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ... ## $ iris :'data.frame': 150 obs. of 5 variables: ## ..$ Sepal.Length: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... ## ..$ Sepal.Width : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... ## ..$ Petal.Length: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... ## ..$ Petal.Width : num [1:150] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... ## ..$ Species : chr [1:150] "setosa" "setosa" "setosa" "setosa" ... `export_list()` makes it easy to export a list of (possibly named) data frames to multiple files: ``` r export_list(m, "%s.tsv") c("mtcars.tsv", "iris.tsv") %in% dir() ``` ## [1] TRUE TRUE ## Other projects ### GUIs - [**rioweb**](https://github.com/lbraglia/rioweb) that provides access to the file conversion features of rio. - [**GREA**](https://github.com/Stan125/GREA/) is an RStudio add-in that provides an interactive interface for reading in data using rio. ### Similar packages - [**reader**](https://cran.r-project.org/package=reader) handles certain text formats and R binary files - [**io**](https://cran.r-project.org/package=io) offers a set of custom formats - [**ImportExport**](https://cran.r-project.org/package=ImportExport) focuses on select binary formats (Excel, SPSS, and Access files) and provides a Shiny interface. - [**SchemaOnRead**](https://cran.r-project.org/package=SchemaOnRead) iterates through a large number of possible import methods until one works successfully rio/man/0000755000176200001440000000000014502270161011614 5ustar liggesusersrio/man/import.Rd0000644000176200001440000002337014502270161013422 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/import.R \name{import} \alias{import} \title{Import} \usage{ import( file, format, setclass = getOption("rio.import.class", "data.frame"), which, ... ) } \arguments{ \item{file}{A character string naming a file, URL, or single-file .zip or .tar archive.} \item{format}{An optional character string code of file format, which can be used to override the format inferred from \code{file}. Shortcuts include: \dQuote{,} (for comma-separated values), \dQuote{;} (for semicolon-separated values), and \dQuote{|} (for pipe-separated values).} \item{setclass}{An optional character vector specifying one or more classes to set on the import. By default, the return object is always a \dQuote{data.frame}. Allowed values include \dQuote{tbl_df}, \dQuote{tbl}, or \dQuote{tibble} (if using tibble), \dQuote{arrow}, \dQuote{arrow_table} (if using arrow table; the suggested package \code{arrow} must be installed) or \dQuote{data.table} (if using data.table). Other values are ignored, such that a data.frame is returned. The parameter takes precedents over parameters in \dots which set a different class.} \item{which}{This argument is used to control import from multi-object files; as a rule \code{import} only ever returns a single data frame (use \code{\link[=import_list]{import_list()}} to import multiple data frames from a multi-object file). If \code{file} is a compressed directory, \code{which} can be either a character string specifying a filename or an integer specifying which file (in locale sort order) to extract from the compressed directory. For Excel spreadsheets, this can be used to specify a sheet name or number. For .Rdata files, this can be an object name. For HTML files, it identifies which table to extract (from document order). Ignored otherwise. A character string value will be used as a regular expression, such that the extracted file is the first match of the regular expression against the file names in the archive.} \item{\dots}{Additional arguments passed to the underlying import functions. For example, this can control column classes for delimited file types, or control the use of haven for Stata and SPSS or readxl for Excel (.xlsx) format. See details below.} } \value{ A data frame. If \code{setclass} is used, this data frame may have additional class attribute values, such as \dQuote{tibble} or \dQuote{data.table}. } \description{ Read in a data.frame from a file. Exceptions to this rule are Rdata, RDS, and JSON input file formats, which return the originally saved object without changing its class. } \details{ This function imports a data frame or matrix from a data file with the file format based on the file extension (or the manually specified format, if \code{format} is specified). \code{import} supports the following file formats: \itemize{ \item Comma-separated data (.csv), using \code{\link[data.table:fread]{data.table::fread()}} \item Pipe-separated data (.psv), using \code{\link[data.table:fread]{data.table::fread()}} \item Tab-separated data (.tsv), using \code{\link[data.table:fread]{data.table::fread()}} \item SAS (.sas7bdat), using \code{\link[haven:read_sas]{haven::read_sas()}} \item SAS XPORT (.xpt), using \code{\link[haven:read_xpt]{haven::read_xpt()}} \item SPSS (.sav), using \code{\link[haven:read_spss]{haven::read_sav()}} \item SPSS compressed (.zsav), using \code{\link[haven:read_spss]{haven::read_sav()}}. \item Stata (.dta), using \code{\link[haven:read_dta]{haven::read_dta()}} \item SPSS Portable Files (.por), using \code{\link[haven:read_spss]{haven::read_por()}}. \item Excel (.xls and .xlsx), using \code{\link[readxl:read_excel]{readxl::read_xlsx()}} or \code{\link[readxl:read_excel]{readxl::read_xls()}}. Use \code{which} to specify a sheet number. \item R syntax object (.R), using \code{\link[base:dput]{base::dget()}} \item Saved R objects (.RData,.rda), using \code{\link[base:load]{base::load()}} for single-object .Rdata files. Use \code{which} to specify an object name for multi-object .Rdata files. This can be any R object (not just a data frame). \item Serialized R objects (.rds), using \code{\link[base:readRDS]{base::readRDS()}}. This can be any R object (not just a data frame). \item Serialized R objects (.qs), using \code{\link[qs:qread]{qs::qread()}}, which is significantly faster than .rds. This can be any R object (not just a data frame). \item Epiinfo (.rec), using \code{\link[foreign:read.epiinfo]{foreign::read.epiinfo()}} \item Minitab (.mtp), using \code{\link[foreign:read.mtp]{foreign::read.mtp()}} \item Systat (.syd), using \code{\link[foreign:read.systat]{foreign::read.systat()}} \item "XBASE" database files (.dbf), using \code{\link[foreign:read.dbf]{foreign::read.dbf()}} \item Weka Attribute-Relation File Format (.arff), using \code{\link[foreign:read.arff]{foreign::read.arff()}} \item Data Interchange Format (.dif), using \code{\link[utils:read.DIF]{utils::read.DIF()}} \item Fortran data (no recognized extension), using \code{\link[utils:read.fortran]{utils::read.fortran()}} \item Fixed-width format data (.fwf), using a faster version of \code{\link[utils:read.fwf]{utils::read.fwf()}} that requires a \code{widths} argument and by default in rio has \code{stringsAsFactors = FALSE} \item gzip comma-separated data (.csv.gz), using \code{\link[utils:read.table]{utils::read.table()}} with \code{row.names = FALSE} and \code{stringsAsFactors = FALSE} \item \href{https://github.com/csvy}{CSVY} (CSV with a YAML metadata header) using \code{\link[data.table:fread]{data.table::fread()}}. \item Apache Arrow Parquet (.parquet), using \code{\link[arrow:read_parquet]{arrow::read_parquet()}} \item Feather R/Python interchange format (.feather), using \code{\link[arrow:read_feather]{arrow::read_feather()}} \item Fast storage (.fst), using \code{\link[fst:write_fst]{fst::read.fst()}} \item JSON (.json), using \code{\link[jsonlite:fromJSON]{jsonlite::fromJSON()}} \item Matlab (.mat), using \code{\link[rmatio:read.mat]{rmatio::read.mat()}} \item EViews (.wf1), using \code{\link[hexView:readEViews]{hexView::readEViews()}} \item OpenDocument Spreadsheet (.ods, .fods), using \code{\link[readODS:read_ods]{readODS::read_ods()}} or \code{\link[readODS:read_ods]{readODS::read_fods()}}. Use \code{which} to specify a sheet number. \item Single-table HTML documents (.html), using \code{\link[xml2:read_xml]{xml2::read_html()}}. There is no standard HTML table and we have only tested this with HTML tables exported with this package. HTML tables will only be read correctly if the HTML file can be converted to a list via \code{\link[xml2:as_list]{xml2::as_list()}}. This import feature is not robust, especially for HTML tables in the wild. Please use a proper web scraping framework, e.g. \code{rvest}. \item Shallow XML documents (.xml), using \code{\link[xml2:read_xml]{xml2::read_xml()}}. The data structure will only be read correctly if the XML file can be converted to a list via \code{\link[xml2:as_list]{xml2::as_list()}}. \item YAML (.yml), using \code{\link[yaml:yaml.load]{yaml::yaml.load()}} \item Clipboard import, using \code{\link[utils:read.table]{utils::read.table()}} with \code{row.names = FALSE} \item Google Sheets, as Comma-separated data (.csv) \item GraphPad Prism (.pzfx) using \code{\link[pzfx:read_pzfx]{pzfx::read_pzfx()}} } \code{import} attempts to standardize the return value from the various import functions to the extent possible, thus providing a uniform data structure regardless of what import package or function is used. It achieves this by storing any optional variable-related attributes at the variable level (i.e., an attribute for \code{mtcars$mpg} is stored in \code{attributes(mtcars$mpg)} rather than \code{attributes(mtcars)}). If you would prefer these attributes to be stored at the data.frame-level (i.e., in \code{attributes(mtcars)}), see \code{\link[=gather_attrs]{gather_attrs()}}. After importing metadata-rich file formats (e.g., from Stata or SPSS), it may be helpful to recode labelled variables to character or factor using \code{\link[=characterize]{characterize()}} or \code{\link[=factorize]{factorize()}} respectively. } \note{ For csv and txt files with row names exported from \code{\link[=export]{export()}}, it may be helpful to specify \code{row.names} as the column of the table which contain row names. See example below. } \examples{ ## For demo, a temp. file path is created with the file extension .csv csv_file <- tempfile(fileext = ".csv") ## .xlsx xlsx_file <- tempfile(fileext = ".xlsx") ## create CSV to import export(iris, csv_file) ## specify `format` to override default format: see export() export(iris, xlsx_file, format = "csv") ## basic import(csv_file) ## You can certainly import your data with the file name, which is not a variable: ## import("starwars.csv"); import("mtcars.xlsx") ## Override the default format ## import(xlsx_file) # Error, it is actually not an Excel file import(xlsx_file, format = "csv") ## import CSV as a `data.table` import(csv_file, setclass = "data.table") ## import CSV as a tibble (or "tbl_df") import(csv_file, setclass = "tbl_df") ## pass arguments to underlying import function ## data.table::fread is the underlying import function and `nrows` is its argument import(csv_file, nrows = 20) ## data.table::fread has an argument `data.table` to set the class explicitely to data.table. The ## argument setclass, however, takes precedents over such undocumented features. class(import(csv_file, setclass = "tibble", data.table = TRUE)) ## the default import class can be set with options(rio.import.class = "data.table") ## option(rio.import.class = "tibble"), or option(rio.import.class = "arrow") } \seealso{ \code{\link[=import_list]{import_list()}}, \code{\link[=characterize]{characterize()}}, \code{\link[=gather_attrs]{gather_attrs()}}, \code{\link[=export]{export()}}, \code{\link[=convert]{convert()}} } rio/man/rio.Rd0000644000176200001440000000600414476052611012704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rio.R \docType{package} \name{rio} \alias{rio} \alias{rio-package} \title{A Swiss-Army Knife for Data I/O} \description{ The aim of rio is to make data file input and output as easy as possible. \code{\link[=export]{export()}} and \code{\link[=import]{import()}} serve as a Swiss-army knife for painless data I/O for data from almost any file format by inferring the data structure from the file extension, natively reading web-based data sources, setting reasonable defaults for import and export, and relying on efficient data import and export packages. An additional convenience function, \code{\link[=convert]{convert()}}, provides a simple method for converting between file types. Note that some of rio's functionality is provided by \sQuote{Suggests} dependendencies, meaning they are not installed by default. Use \code{\link[=install_formats]{install_formats()}} to make sure these packages are available for use. } \examples{ # export library("datasets") export(mtcars, csv_file <- tempfile(fileext = ".csv")) # comma-separated values export(mtcars, rds_file <- tempfile(fileext = ".rds")) # R serialized export(mtcars, sav_file <- tempfile(fileext = ".sav")) # SPSS # import x <- import(csv_file) y <- import(rds_file) z <- import(sav_file) # convert sav (SPSS) to dta (Stata) convert(sav_file, dta_file <- tempfile(fileext = ".dta")) # cleanup unlink(c(csv_file, rds_file, sav_file, dta_file)) } \references{ \href{https://github.com/Stan125/GREA}{GREA} provides an RStudio add-in to import data using rio. } \seealso{ \code{\link[=import]{import()}}, \code{\link[=import_list]{import_list()}}, \code{\link[=export]{export()}}, \code{\link[=export_list]{export_list()}}, \code{\link[=convert]{convert()}}, \code{\link[=install_formats]{install_formats()}} } \author{ \strong{Maintainer}: Chung-hong Chan \email{chainsawtiney@gmail.com} (\href{https://orcid.org/0000-0002-6232-7530}{ORCID}) Authors: \itemize{ \item Jason Becker \email{jason@jbecker.co} \item David Schoch \email{david@schochastics.net} (\href{https://orcid.org/0000-0003-2952-4812}{ORCID}) \item Thomas J. Leeper \email{thosjleeper@gmail.com} (\href{https://orcid.org/0000-0003-4097-6326}{ORCID}) } Other contributors: \itemize{ \item Geoffrey CH Chan \email{gefchchan@gmail.com} [contributor] \item Christopher Gandrud [contributor] \item Andrew MacDonald [contributor] \item Ista Zahn [contributor] \item Stanislaus Stadlmann [contributor] \item Ruaridh Williamson \email{ruaridh.williamson@gmail.com} [contributor] \item Patrick Kennedy [contributor] \item Ryan Price \email{ryapric@gmail.com} [contributor] \item Trevor L Davis \email{trevor.l.davis@gmail.com} [contributor] \item Nathan Day \email{nathancday@gmail.com} [contributor] \item Bill Denney \email{wdenney@humanpredictions.com} (\href{https://orcid.org/0000-0002-5759-428X}{ORCID}) [contributor] \item Alex Bokov \email{alex.bokov@gmail.com} (\href{https://orcid.org/0000-0002-0511-9815}{ORCID}) [contributor] } } rio/man/import_list.Rd0000644000176200001440000000600214502270161014446 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/import_list.R \name{import_list} \alias{import_list} \title{Import list of data frames} \usage{ import_list( file, setclass = getOption("rio.import.class", "data.frame"), which, rbind = FALSE, rbind_label = "_file", rbind_fill = TRUE, ... ) } \arguments{ \item{file}{A character string containing a single file name for a multi-object file (e.g., Excel workbook, zip file, or HTML file), or a vector of file paths for multiple files to be imported.} \item{setclass}{An optional character vector specifying one or more classes to set on the import. By default, the return object is always a \dQuote{data.frame}. Allowed values include \dQuote{tbl_df}, \dQuote{tbl}, or \dQuote{tibble} (if using tibble), \dQuote{arrow}, \dQuote{arrow_table} (if using arrow table; the suggested package \code{arrow} must be installed) or \dQuote{data.table} (if using data.table). Other values are ignored, such that a data.frame is returned. The parameter takes precedents over parameters in \dots which set a different class.} \item{which}{If \code{file} is a single file path, this specifies which objects should be extracted (passed to \code{\link[=import]{import()}}'s \code{which} argument). Ignored otherwise.} \item{rbind}{A logical indicating whether to pass the import list of data frames through \code{\link[data.table:rbindlist]{data.table::rbindlist()}}.} \item{rbind_label}{If \code{rbind = TRUE}, a character string specifying the name of a column to add to the data frame indicating its source file.} \item{rbind_fill}{If \code{rbind = TRUE}, a logical indicating whether to set the \code{fill = TRUE} (and fill missing columns with \code{NA}).} \item{\dots}{Additional arguments passed to \code{\link[=import]{import()}}. Behavior may be unexpected if files are of different formats.} } \value{ If \code{rbind=FALSE} (the default), a list of a data frames. Otherwise, that list is passed to \code{\link[data.table:rbindlist]{data.table::rbindlist()}} with \code{fill = TRUE} and returns a data frame object of class set by the \code{setclass} argument; if this operation fails, the list is returned. } \description{ Use \code{\link[=import]{import()}} to import a list of data frames from a vector of file names or from a multi-object file (Excel workbook, .Rdata file, zipped directory in a zip file, or HTML file) } \examples{ ## For demo, a temp. file path is created with the file extension .xlsx xlsx_file <- tempfile(fileext = ".xlsx") export( list( mtcars1 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars3 = mtcars[21:32, ] ), xlsx_file ) # import a single file from multi-object workbook import(xlsx_file, sheet = "mtcars1") # import all worksheets, the return value is a list import_list(xlsx_file) # import and rbind all worksheets, the return valye is a data frame import_list(xlsx_file, rbind = TRUE) } \seealso{ \code{\link[=import]{import()}}, \code{\link[=export_list]{export_list()}}, \code{\link[=export]{export()}} } rio/man/install_formats.Rd0000644000176200001440000000133614476051106015315 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/suggestions.R \name{install_formats} \alias{install_formats} \title{Install rio's \sQuote{Suggests} Dependencies} \usage{ install_formats(...) } \arguments{ \item{\dots}{Additional arguments passed to \code{\link[utils:install.packages]{utils::install.packages()}}.} } \value{ \code{NULL} } \description{ This function installs various \sQuote{Suggests} dependencies for rio that expand its support to the full range of support import and export formats. These packages are not installed or loaded by default in order to create a slimmer and faster package build, install, and load. } \examples{ \donttest{ if (interactive()) { install_formats() } } } rio/man/get_info.Rd0000644000176200001440000000276114476631364013723 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{get_info} \alias{get_info} \alias{get_ext} \title{Get File Info} \usage{ get_info(file) get_ext(file) } \arguments{ \item{file}{A character string containing a filename, file path, or URL.} } \value{ For \code{\link[=get_info]{get_info()}}, a list is return with the following slots \itemize{ \item \code{input} file extension or information used to identify the possible file format \item \code{format} file format, see \code{format} argument of \code{\link[=import]{import()}} \item \code{type} "import" (supported by default); "suggest" (supported by suggested packages, see \code{\link[=install_formats]{install_formats()}}); "enhance" and "known " are not directly supported; \code{NA} is unsupported \item \code{format_name} name of the format \item \code{import_function} What function is used to import this file \item \code{export_function} What function is used to export this file \item \code{file} \code{file} } For \code{\link[=get_ext]{get_ext()}}, just \code{input} (usually file extension) is returned; retained for backward compatibility. } \description{ A utility function to retrieve the file information of a filename, path, or URL. } \examples{ get_info("starwars.xlsx") get_info("starwars.ods") get_info("https://github.com/ropensci/readODS/raw/v2.1/starwars.ods") get_info("~/duran_duran_rio.mp3") get_ext("clipboard") ## "clipboard" get_ext("https://github.com/ropensci/readODS/raw/v2.1/starwars.ods") } rio/man/convert.Rd0000644000176200001440000000341114476051106013570 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/convert.R \name{convert} \alias{convert} \title{Convert from one file format to another} \usage{ convert(in_file, out_file, in_opts = list(), out_opts = list()) } \arguments{ \item{in_file}{A character string naming an input file.} \item{out_file}{A character string naming an output file.} \item{in_opts}{A named list of options to be passed to \code{\link[=import]{import()}}.} \item{out_opts}{A named list of options to be passed to \code{\link[=export]{export()}}.} } \value{ A character string containing the name of the output file (invisibly). } \description{ This function constructs a data frame from a data file using \code{\link[=import]{import()}} and uses \code{\link[=export]{export()}} to write the data to disk in the format indicated by the file extension. } \examples{ ## For demo, a temp. file path is created with the file extension .dta (Stata) dta_file <- tempfile(fileext = ".dta") ## .csv csv_file <- tempfile(fileext = ".csv") ## .xlsx xlsx_file <- tempfile(fileext = ".xlsx") ## Create a Stata data file export(mtcars, dta_file) ## convert Stata to CSV and open converted file convert(dta_file, csv_file) import(csv_file) ## correct an erroneous file format export(mtcars, xlsx_file, format = "tsv") ## DON'T DO THIS ## import(xlsx_file) ## ERROR ## convert the file by specifying `in_opts` convert(xlsx_file, xlsx_file, in_opts = list(format = "tsv")) import(xlsx_file) ## convert from the command line: ## Rscript -e "rio::convert('mtcars.dta', 'mtcars.csv')" } \seealso{ \href{https://lbraglia.github.io/}{Luca Braglia} has created a Shiny app called \href{https://github.com/lbraglia/rioweb}{rioweb} that provides access to the file conversion features of rio through a web browser. } rio/man/gather_attrs.Rd0000644000176200001440000000227614500666516014614 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gather_attrs.R \name{gather_attrs} \alias{gather_attrs} \alias{spread_attrs} \title{Gather attributes from data frame variables} \usage{ gather_attrs(x) spread_attrs(x) } \arguments{ \item{x}{A data frame.} } \value{ \code{x}, with variable-level attributes stored at the data frame level. } \description{ \code{gather_attrs} moves variable-level attributes to the data frame level and \code{spread_attrs} reverses that operation. } \details{ \code{\link[=import]{import()}} attempts to standardize the return value from the various import functions to the extent possible, thus providing a uniform data structure regardless of what import package or function is used. It achieves this by storing any optional variable-related attributes at the variable level (i.e., an attribute for \code{mtcars$mpg} is stored in \code{attributes(mtcars$mpg)} rather than \code{attributes(mtcars)}). \code{gather_attrs} moves these to the data frame level (i.e., in \code{attributes(mtcars)}). \code{spread_attrs} moves attributes back to the variable level. } \seealso{ \code{\link[=import]{import()}}, \code{\link[=characterize]{characterize()}} } rio/man/characterize.Rd0000644000176200001440000000357514476051106014567 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/characterize.R \name{characterize} \alias{characterize} \alias{factorize} \alias{characterize.default} \alias{characterize.data.frame} \alias{factorize.default} \alias{factorize.data.frame} \title{Character conversion of labelled data} \usage{ characterize(x, ...) factorize(x, ...) \method{characterize}{default}(x, ...) \method{characterize}{data.frame}(x, ...) \method{factorize}{default}(x, coerce_character = FALSE, ...) \method{factorize}{data.frame}(x, ...) } \arguments{ \item{x}{A vector or data frame.} \item{\dots}{additional arguments passed to methods} \item{coerce_character}{A logical indicating whether to additionally coerce character columns to factor (in \code{factorize}). Default \code{FALSE}.} } \value{ a character vector (for \code{characterize}) or factor vector (for \code{factorize}) } \description{ Convert labelled variables to character or factor } \details{ \code{characterize} converts a vector with a \code{labels} attribute of named levels into a character vector. \code{factorize} does the same but to factors. This can be useful at two stages of a data workflow: (1) importing labelled data from metadata-rich file formats (e.g., Stata or SPSS), and (2) exporting such data to plain text files (e.g., CSV) in a way that preserves information. } \examples{ ## vector method x <- structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3)) characterize(x) factorize(x) ## data frame method x <- data.frame(v1 = structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3)), v2 = structure(c(1,0,0,1), labels = c("foo" = 0, "bar" = 1))) str(factorize(x)) str(characterize(x)) ## Application csv_file <- tempfile(fileext = ".csv") ## comparison of exported file contents import(export(x, csv_file)) import(export(factorize(x), csv_file)) } \seealso{ \code{\link[=gather_attrs]{gather_attrs()}} } rio/man/figures/0000755000176200001440000000000014500616167013270 5ustar liggesusersrio/man/figures/logo.png0000644000176200001440000012370114500615377014744 0ustar liggesusersPNG  IHDR pHYs M M=@tEXtSoftwarewww.inkscape.org< IDATxwTߙuVҋH JS(Es &1h,WBrMDI4 H * ".l϶i|.3Ϝ}"{(  LrlLU2(AAPTC:&η@B j&zN-ڋT"XAAPXҷsA%\¶ܵ kqLl3_F9A{(8[nZAlT|´v+YAA9YO}wίAAz| іV`% `]ЄIОatGAU@1'>G.\AA*':g AW2n?o#~y w DnuW M[ş׾_  Z +@[b3A=(x cVA4 OPo| oMq Jc!f,_LJ3lV:,Kڗ /k x1!x9"_u$6q>T:Ap5<o3i/ )KLs* s&r\Y|S:Ap<o1X ܍+! Z8S@hinxnr6OSU "F' cStzTUjJbEM5n;cD5He*,& x&Sp ԻB@ H&V:~ϑۼnG/4>z"AY6SZr7oXU_ HA^zZhQ$\!s+$s&*b"y j N@O#abҒe&s&LJ6[*x<!kj0]`17Huӑ4nuKs3ۿVcUTpU."y J?AntZhVaS:5Wy_Rgy3 L"y Jy\ۋ8*Q:թ"͍T=MڍT8t(@^ҁ'ЛEFi7&B?8L1]P:ζCP1< p,t,Mӑb\ݙ)KXm[ V8AD:kiG BXZIZ 'x.:cPZN缾_8 "y MG^z2F8:0H%~b)d5gϓFOS:"/m٫t :)!o\@3Dw|.t(+;4C@± ӻY1} C-d"g)FUm}V ٤p,BDNxW86[/[πPT QC4x&\O$O3ydi/`H" +,MČ)b0Wf3;v*Fu+Q-\O|Zy>p,$DK=&M5nFg;4_){Mp"yz9KOTU ?K0D T:n3UW1=\T@3 CzioP)K+]`17HuVaӴn}k^T5P+N$OϠ~܇S5ۋHZ-ӯ v{PUA&>ya@±|*bnj[.͵)}Ip+CZQAEDT9%ZUBCƏ"Ꭵ) 8E}~!Y6SC$ҁmDTq5)H{Iį\LPPCSHʘ\t Gr ~ԳTԠ|6k7Ruҡtr)wҁx<]+xt D|!cG* ZdSqҡ! SXHN~TROO눺j$h'}anh/{#MJ^-G-D"y:Hcis^茪YF*nUc5됯J'yDt Gb1E,MČ)b0AP K>MUJ^K' cq;ZZ J鈘9Mkm,ͪjWxD9ꩪ2~ +`t( A}^k7QqHuK(;ɳwIsҁ7( 3\PAAdSClp/j"gB5w.0o[ 45Q7nzixJXTI$ϮtO Jj>%* X^Am}Smrɳ%JҞq0V,/.FPApsdHɳJ}wJ"y⑯4+H{Q.GEWX({[hPt4Y(=y ||P!fHz BfS[yvu%oM--^ŭn[>X5HAPPCI9·{3㡛D ޘN-AYgX$M'bcq o~~*HXZi >D^w17݀נt8 ZҤJۗ9z,OOsKE`t( BmGULӁ_(xjLC^yҁO t( x#'\|ClsJh<Ð5FE[z 8_y+͵uJ^*T8@èE$k$v~J#hl,fUm}/Uf OH3K#=4^lҡj2Z3Jȥ]JbwNW=ߘH/"dr ^a2؀DPڳ_Y bwLȿGլ=:nI'Z F ?w?ޤt8 [Sˀ? Ҧ޲荪YF*ECi99o˅ԶY6rJW<'"לt Gb1EjΞ' TP:v ;pR{~|ũX}x]t( iiwhP 3yxHXԉ?pe|±|}-C+ &[?#O4^9X蟐׊e Q8Ha|)C~% e>ЈE]{ v؄Au5,j=١~^:'-T SCҁ930U@ @ Q:8p˙;6 .M$ |ӡ܉KK^M7;}GVyJC+#yDe-! Z8SSABs\ݜ} 1fIs(%dhBƍ.'_M?F&`pqI bc>{ޡ44 0 8L`k@Y NbGu.|S6MMrjٸ oh&_>*Up_ hltS+$CS:jd`1 ^c>ȓu`Gc9{ s I"|.'4{pw/QqÏs0lXÏ l:MW˙3ٜ=KaGÜ9`/iX,TtY:69kЩf՞LdS { {?\UHCIX$CQÎvHw0(-ص0% '>H8w._3|3&qRIJDL@jכ<޽G*pď~`208Nw |X]ٻRVH_)r[iIn6 vL*5yOw@>a!.U3]N> : lVEEe]wۿS5cسHŲe7p Ę={}}~ǘ;ƏW>: w'i5MPs[?zc&1ΑaŭϲoJhڳk}_ _m"Ci|Dx C[ED8t> eĉ#zL[qc92N̴hYO멯yi/=իdĈS g10nbo6[$ gK s2o#/&T@3BUI?!S9)U^x~'yK'Eÿ$lx4*XnJ|&o˜1)=BB)VrDF_ҥY}_?.Fc{F$Fl߾{hE<}US5Nj9Z~D7~z~h|Jc0]pv;!] ][<ӀȝT?1y{]K=G*n?=ʕ4H}ߪ5 S tҤ\u%VtokǍK}uΞ All_~aT=??HLTl&4b~}+=2g2`e\vm,Bn#r{T CTVabn# ^ oa~LG$^Y9rϯiɓ}lȐX^|(/⣏vqYJ%%%9s뮿 o7ˏ+TtX"Y,(=ƒh-m2?O欟:;)8*ϭpn_3翀'%E=r ].APVKuW1O;8Hu,Θpn}Î #;_a6Kw1h~Lffߡ :ƍq}/sAΞ͡B<Ŗ-_b43rdȦMgp{r`]N3o̍ܙזDӮ[I^LX.gMKSԶ_Axt[2kj&G1IX8CK\IHI~~zy}"_o?d>Ѩ}u{hUʯm2V m=^-Ry!q~ӆ IDATYtA$\>JP E^rcZg2 zIw3UO䙚9ӼyWy.))-kOaYnز^mX9S81hoɑ#dWb&ghD4i-v oG,*dOӿ&_`hbT 9R܃\U]?1 fyHZ z&za D\;77R}봝AJy^%"- _H|_Xɹ ۷r䕧=WjZ~&|JsY,4aBZm[\5\lG ׵bs?1wTWM!ۨu͞&ph<̅owhT4ŒCkwwLpFKR"ڱԄΫ'yPYYC^^%`Z*Я'2e?Dq˒gm{'f8j(!I v9`g} Ʀ_ODݶ@mTI#`nM$➂"wQd_{6ɁeTۗ8qަq\.CVS2$w9}:"Wbc)(-؊";Yj1 1j &$y6mU=uWp6\FΆ)cpi H K~ѷ&$>' ȭynd_ٜ<+*z.y3YKaa=RbMHqrԏ?z.+NK,e>ߡA5:Vk&+?)`}?r2n.'evIԇ3hl"fL}lб$%+%2SN+±'sP688<}aKݝHdf|˺_z][[@r%ι4,OyP3lkF k }Hxnr6~NMVK5Wx.Z?e7Ibf|(7 XfKv"ʶlkjɱ}pwcX,9szZzcmosn; u Q{1}'$ r|p:Vvj&|W苏HZ-WO%lxr|HXӒgQ$X!2' <-Nְ.й%ZUzj$ЛͶ!6ֶ]VV_ɇa}#:~/)1=޶6|cy&ObVKZΡA'i05oZlQPAjj6JV.&b4npvy}@ߘ(/$x@EAN%RS3O:Dk=Wʟ}5n\j3fsOSV,-yQC۸$Iwbb~|0yѼib%3 $_Ԍ5&J*`6 "a2܈CRo:-ڶAKi]SQe[{& 3fh56Ovx;[ohh6ϝ{%|MOoqSmsf v첒fcq,zcfUN|BNg8t3u]OԬ"qAj?k&%q[jdk<^Zα>eSf t =ٓK/δilz|}Wmmr9NtcSz$Iz=?nu|=+\jb;$N /MclJMf{&5k^c*aț(^W))6AMmm=~]bb >{MyTiioʤI} $$?ѣrs:/yyxᅷܛ{|cd=Ic%'*Gpm XP?<]@-%Z0iOԩ~O5 yde3[裝=>h &d&ΝvbޣLh}__.gs*+ 5ELL}˫?kґG礡DK-/l鸔!] rp~ ցHRCYElYJkyD>y5[XiONF"11K.΂3lnrݧ{ ;55ۖgd>>(b苺:>';֧4 NYYv<67+Wǻmj**Yl.]S||yP;XbHse@XŠvֲD5E oIVregs}~MW}_Z[[ϓOoleٲ:u=wDf|nv<bR=n5uVc4*pM#چ&KkwZJ۾ŪDkӞ|ol_^.|ġ;˚5@$b2$Xk)..#3;.yɳh0;`VT苟A|z CKvp|/h>(Ì 4ӞB`69t4[~1 bp\nu~j7i(s\n)rIϣ얔b Fia,T=X\[ש`m;aH Wo?s׻_p&X8ᖎURhFke7WkGɳB}u,JX-kd}z!ݲS2dH M$rgÝlm;qHRR9u*˦ pVߐOYx`qU(2/;)/4&d <L Ssm|(ZI46&A[4G-o3a=]w. jx亡~~ZĹ@>zSv LMfACA«yF-5m{6VzG.JehgƇj+іva#[<,((ܶ0 b!>|' .wIBݔFx`+Fyߝ+yg Dtz:M[xq%ZlX癖hlla6ٹ sLSSe$!:};_ŃWчm<ʳ*$Dˢ|<m~m-WD%+&bxC>2*YZʖCiٷ9yN:u]wwDFFraC!Р7sS:u`6^y²e XPG%=ˆE3f`[C%C]Vʆ䙚hM{X&'3 v"##/1bǏgӦMdd} ^X0A!LMf~i?T+𠒭5e&ҳKH*z᪈G%|4 wW iMFT8[<;y^Lf$vWgٞ Nlslao򬭭g6~DcX[Fyꩧ8s ;wdժUمdh>K*_,vV]5|#G$OVֱ̓<,-Ie+<11U#cZ63*X'ɥѵomi_\\FIIͯo?)S}~wW;v1Fɓy(,,d֭,Zʠ>ZpSOސ^ݎS%,Nw^٧{gfNdPc>#ʶ5Ml9S̸P֞(d6AVnls.,ZϪ=%'G~xM㵗\2_jk0 $$$____fϞٳ)--eͬ[]vatNM /뻳 ^<̤g0$&P^Q<)r8A,(z9m6[,|[E.`JNjQXX٤W'䫯;$5KLLdǷߒ׆j*VZEzz:6l`ݺu={ǚ3*'nHO߱s΅~3}l^2 ]M~>:C3oXcvKʳ( ݔyLTۆEIO*<~yL GN?<ŒDDn8l rVSyPw6|8;%z`Ï=a?CJJJϋ2x}ntP6ηQ\ʳ²N畋Y Ӂ4YSf6[,l*㑝gٕWaӞ*Jm~}gǏ3 36aɈ1݄8<cӆ`O/JmC3s5;+ʪ9UJC,o"$xⲤ%Z< $b{!_?mͺtݽpcKwO~ayFD^^2n(u,{G>9^@3VQڳti㞓n>NzrJBu(~>n(_L[{qٶ&3b UζniӸGn8 ;>$,zv :7E7jyTN͂8UCAi{ՂA4 \O$>h)ޚI`k.s5}-ۚf*+#O*3O8̷TtcON-h`/<{dcHk0Dl'5ԟiQM@8QZúBrUViyh8WDžʡ\қӦMs9L&o&k֬!77stb6Sc-E;ւc2i;{K TmxuH3CiH8[2<-KY{eS/ UVqoF#r /3fKb髦 73wy, q KBfK6,M.ذ\QIiD{ TWiihWDžjy>*k+6/͝.K-|||Xj+W/dpq]n:o?Ecya$Lu?Gv19aXwZH%[AQ^( ^ZǬh4[ؖQG%4UX$}YIuyJhe[S !2t[Z9|ko[ȡٱSPG%σUl>S̞J5ZϹDkH\tv $,]!]5cd!{34Vu}OAs2[HǺe8:|;+㒧%ڎhOձ.=*uL^M<-%,{J:=QI ]KoÙP~c*0< @cJ l8U%O")w GwtyLo eZ6l V,aG?00;F0 H`Rts&KV+OOS/~ ]2k# ~յJ㉎f޽mwDtD+ҢnmzY-NS]+canAHS9Nū _/ۯ#a4W8!:A~VqO$}Y=1U#c.&NDwO/p "y{8;&ΐ2䧯.q}D/_ΡC;$ kVeĕg?{o-ۺS %n[csz)|||8||DŽ /ɳZJFZwiq5b[>8B^@dFRRV:t(˖-<}}᪫\ J$^$X9<$c[ym9ht`7m{4%O p-&Mm|'tpYZpq3<2oHxmMn\FͰ&yZ,\سO_-eJ5wݦWL¿ud.] #G0^W"yv$.%Z5nm7tS o77ƴ)&O|橧B?:$/MqDl'5ԟiQĵHDi J/Wړ8<8c~/}P@3r0i/%%[n߇ aP%^ t,IhcXKvW^9TE̍];SAs@wn(Τj0a|M}܍%ŝJf6.tmj?KS#xp DmW-cA)1~F"s'M`Ĉ,XcIkgKiݻDyap ۦcrzP*<,f͚.Å E%}35ԟiQv*Ѯ;O^Wl HćrS/M YU&4٦"y*Bt.i-|̵.\@hܟcVG'O%&6,Z-W.W}"~RIe H"s␸_S+I\!%ZgѺkt{)\7koA<.yPEjYFㅥ[g5,$&;2yiaМ vsv|qI gt#>WER-%mͽx}*XFㅓV*;3d{ "EA Mi6,[tU׾-ۮJU: !!$$dLfH2dgN9˜sC2s?<L4!$,{{GR_Uڷzv%}i'%Ek ox]>e)C-ouC.EEEćild2q\ǪeJ" gEjHv,Szd [ln[#P:gڵ,0͸ZbǑ#\We lhM|tS.7%xT9|1ac;<ɓیl?wS0Ʒ b4xwNDmmPI1_m6/{(c{Vnhl䢱@&"x0%F oyfggwz{sS2I],jAmټa3nq~ wn@E|X:8S6B ;68V x RRZ)PeR&V_,*\C o_S }8py&Y jǯba!wD?4?4$p#JOݻی'GD/mQ7%^HhmBu>(Imwr &^xm,7]va2PXtbbڦ* "lquO;Zc3ߗSbjm酜-s]NK&CxgPCڼUΒ]oɓ| cټ~=wy1'!#G|(W'j#7 k*WO>KV)ڳz-<)m;D /MϧlzR~m7رC('jҤ6?o=eHnxx,hePA5fQeㆩ$aZ KۤhX-ԾΝ;ygW ҴȲV.% Af,kE.H(R }C'k%5~9N^ z͛fcqnھa\` Z-ՍYGRn 䫢唻\65<iHl )S9_[xdtᔁ籏N]8#f#''mƷ=nռp6D 16"x0%FzU\iVA3:ku/m]˗!huxpD1ٌ O'N@`wxv0?vM\D:l w=ٳ{|Η︃ .pV("7 fllNfpK-X¹L1S:NbiWT8Hyy96Ode1jWV QgS yvV S4IG'&;Fi270}4vCXpvz֭c ; oӇ&L෇\i(/˒2 *|!K]K]P>Wk 0=^Qu#?XN<ɴ;d_\bǏ|۩VSt"DVbm+|U*%E椁y=ECY.+BEw#,qŅ:'OɓU:b kjӧm_՞Uׂ"}+p9y %(]Khjy(50J <{gNFN1YlR Ԫe?=٘erdIF-od֭L;j,z}yaW ^/><˨Ȗ[3M2C/57ЏI⩒$=MNlcWh y)??z%JzS8s7L/lUsϠ(%6׵=Ek{y 佥ct;oň,pQ9[3pyxHܕOb= γX8UKɼ\[rLh}-3 잢}sh^f} ϳgTqH4j5яC2h.F%$*iEU]pI?ٕN+ì:tpTT4;O£sltĴ)4FC P><_H#Rx^_Ą6/gɫh5\*v9ȯ,СD;9O fGqj:]y>* ZjK&6dշgu τ mp5"MkT=(š=&f:4EkޤmCu>Th!ܤ ;ȲǛ _?e/7U9vRlZe7c#(7f^?a~vu2Nj m£sSv)7EUQ rE' )1kc}]PCie% ~җGMfW0:Q]ZJhPKÄW2h0 3Oj=k 2ȭV^!hƣij I~A~<<4A!-_j.ڬ*uz27"JFޫ dY ]n^WWsihxgx>3UUUY?(K/HVe}Ϯ=,K%#7!-IFq)dY&x| <n؈4Si3` stne8|Cy .Qvxڙ5RM&]r-:»K`D|>K~甡t:6o%cRS dïÓ Ӹm׎L3gCS4Rϙy%-qqZ+˪F3ɯh4b4h|͝z6Hك ҊxuSFN%}}'`jh`3/Ru]vq.[/d… 3tD[5-mbz ťi"5A!-;y\QϚS;7tJ;4ͼ-O8+:*CB˃Hp@t Oa|o8'raf3zwf8)I9*ڗ~͍*Fm\ w^`+E[e0Ef1+]3Ek<4dZU4Ԛ2PVUŮbcCIζ:9^{%=s';;^qnMIi~|}U1\7cI ^2R=׈$[ b542s+x@{H8NF痙eB8od6̷t>>m~?y7(vY}?bDϟŋBni +4ʰ3UpbMXcBE=/Jvy˽# n42ٗ?PXVhچɄRRQa},sO>{-+m1[hl$,4L׮/m޽f Bг+1)*NC<;RcIj|ӋȫF 9Yq:~l`r+qeo:W )6׾F;Zҍ,>6sUg7Ⱥ%/mxڠ%EڼȪ Co9l:SpDGm}=9$^k }|u+5u=>6|i3׊OkӶ-)ڤV)Z؞[k?v/OhѣQww hP>ŷyUz|yFX1guwJ;4)3)h3Su64o\ ͹4b]e=m[orIGsmv # iC}xdd A- 9e׳M !FҶ:{zIz+Az9UFu&E(Tx A̞=*???&C&z ˆcii2iu<hxdDIa-fؗu]#x DW7ۧGGfM̸w>euf %t? Kl-G@%`l/ 2tkYg[v=ME`x ==z4Gk&t44 k¾{m.pDgVŽCK[)|iC5γ,_Я_?O:Ǐs?vu2z*GpzDNghKdٕNwB@yIxO:,혿p!Ϗ'F9 I|.^t8ݦԈFǯtjx1;l"&0$@y >C.\ \., <(2"""b%NatqCrER{og1d^Õ˘e3;2𷣫(W5{/$,jKW_NbCwS:,E@yv̙ñc6lX{…lܿ#GYQGaCu]%uJvfܪ&sE#5t|-D5Ci[xiZGF\\񄅅5XO0aoCCrrr,5ZmoR=JO%"0u]d\‹ {iԬζT̈cG S`!Hĸq8p EGGe5V;?PTSU[YoY&LɓLN =$Şygl9E+~DB;)mHH˗/'dͺ.<ȐD.^Hmj 32JsXƺ1J͌A2`,FYw.w&#j4c2ʧ{LIn;!04vX{1xCfϙS?SpijF\ddK|cbν#3۷seT52s| Bɏ_R8p!NA3((}{=ZpLHHUz=k+zH86_Ϝ ذ?s]og^U+OoyL%`~|Ԗƌ s6o/nJg\e5]kd=yB<.9Ejj*?0=aaaJ#&~;99)Cѕ+ĎOvi)Ky2p0$/dn1ngD h˩kf|M{E;$VKc{|=!0jY`=ӧOW:^3ohNo:]__$Q\^NL;vJPPçqJP$_^RR|#5B<~^yE$>>>Z$W…)lMI]9J~u3l::-ܲ:x491rN)WUCt(#?u͚EmM ǎu5UMM+9i׼tp+hwl3g̗ YcJ8$ zx[jw\!io… A]y(vZ4,8qP'ֳ*m{RDOݶ)?=p3#6uS:rK4)ꛭj7H Ueԩ\ƻ?zQQQq)3)۵e MLVMS}iՒ;1=NꚚO1Sp%U 7»`yi[ou:cn? SMl=|K8:FFsGw|87o&00r-\Hvn.ΝsuA^eK kJl%pk~8. ?OS,82X U,շtCS`$oNxxCntMDEDpaFlZے09#_%#fʗ3Ҋ֭HrO/Y!<=)p̳O>ر8]]$|vRSO93vU\>C.N nNJPIἠJDj)p؆Ho΀]uxw-Xs_YYICR /]:mtqfyQ XnyhԼ' c/X^#!SgPP[laС?1} ~ 7_OTp0IIv=o 9z%j#_W_QZZ0̓[ΝyVJ$:nz B<vWO___V^7lz":ɷ_ԩS~/# Na(Axx R_'v;_,vfꫫ83ԳNgY''lLBzהX~>իs(A$^56j/) JP!z'矷S,z#?y,UQC_Ψhh`Lv!f%h@JPPWUꧼ/,ڪ8 ![޷:wlt^3~y3++;?ES,W/Jd\o.}i\8]%߉z9<._F*ZϫSZx5B<=l;~xWܼo N鱕 5:+Vɑ,1[]kuiN'Uh^7 'B<=ݳwaPZE>oǗvRhm}qY3-ZI`6,\x z4\`Wu2M1;r6Q=y=O l>ϔJPJaRJ(AB9bWlsΟ&./6-;]{K]]Pr=o-WYxU=*D ktK E5ijjBCDDM_Zbj8%݊JҶB7eߪ J-Q'ZW$&"SgDD&Mrp0{.Z8-ؗ}զpe?_Po4R^_v$L6wȥV㧤SrELB ! iG ш+CDNL᥯ħrv NNy|(y(1%AJ IDATwB`):Ou=ҚƄSXRϒIy?OGBZďKoγ*޸$*twH]ђYXTݗ6mtJMcBe-ΘyyÜNJPHV5zI43!ig9sxVgv:ݗ8rJyD e|Z=I$(A! zkh4Ɇ/mlP$MlPBu Gmi s:cd;T)Fܹs<ڗx|i{#ҶB3_$@66IV),; ,̱6c|}aj刣/mog6#4g0\d5&z()}a=l>~ E35/W+s:ѭJPLHǟ"S2$Iݩ}i}Y8Nħ*Y02E:3g#\TK:SrRRv5pխbOvsܸq>iAOPϚ;9[֗vD(K jj0ub:2#Y X^W%|O4e\.YvZ•|i{COS,sSKV%(//WrDh?m+;ldG-=,G2s %(p^PP"9@p! 6sСm+ OQmJAMո}0vXle_ZJÜ!K[:Jf/-AϩR9!:#DChD$Fpߨ9.K̲̹%ui>G7I6%p=ħR`x ǕB>9޾tQz՘$,MѲ[_٢qvA)J<ÙXEME_)9iT:G)];o/:NoT"DNZN̴o!};QP f^an4Pa;a64uS 4~ַ ;x xPj_sb7;'g^UJi]E /%VB+A߰8<'M& e+L\h JG`>~LthYz,{G JCKE3;C_گؕuʗ6/#f-%(ŗ[%7 ws%Ot(ًe]TGu%/cmd:-3xbtj%;}ie#k(JPBLRE4UVz#Żʺf~& n0u\'p->[Va=@f{3,k`2R+ۣsgK{ꍾ;rVK1շǩ|.C/w?k%k$,*O&h,reoρW"{xϹBo[Z=mw jgV>K;yfZruw15qu{Ta5B’F~Е+^G4\-$ͽ]Xmm M@]<'Ҩ>s3? Wp Nvi[ĶC9*mʽf`tQ{ykޤR5|;MMܻf5ft6PKdKľ u^[WOC@±B%zIs1JPe"+c+A,  G4dҡݨNK'Ϩϻt(< \V8vQ\8,-I"1$<mdAi(,&Ϩ<8 R@:]Z~( */qf`*_a'SC#wpuV&9u25OIX;utOwBL >->&h)Kb±t wlҁ&2*@ 63WQt(ى%E{V@z;uaU@,\.k]R/x ؤt ,}Ie&p,_89Ӑ|2U :hh~S"v7R  xx^'x W߃K3BPQy49YIciҡ b7B TW[JJP |w);w&8>[QUam2٦' XA9{q R''a]lED"PTqt3WPX_i%,bix z з;I3:DzWQVm$bqx6g!.)fs|⇘&uQW^'J:I1%VgPa|agREOD>WW|''zwhg<`au&'ZGCͻRUZN[Uu'Xn]muXDt4"FǎS]ZG ڃ{:Whxe@q⒓^0yrԭH]zz~ x+41&ܹN ^yf^nǘ7/'aXuMԮz#xeUG7A"IÝ 7Iߗf7/Ms~^kyJPQxeYNy ("9# QUxD_$0SqW[n}UKH4."r0U(AU:H π 9%$9{ۈO1/Mi-ԬzKjpQ*,\4ގNa WSb [x/{,K3WYG;uGYGYbw\(wu.#u*-䞏;|:hxzBЉA|dιBSS㈄+GQhxzS]-xW͝/N$:zz5+v:@ ^Op,]wYG #/HhxƦ`2 8 2g_x)IQ6n&Ua'TK mv&N΢dκQU/oS]'[t]=Dǟޡ|W`Ћ[ZH%UajX[o)7Gƴ޵i$l5lw_su O`YhGYoGuk6R[*.O45y O3<`3iH1: ર߾@W'6su< x.xŸAүBnq!㬣H?HeI-~Ԭ\CO)8mρ8E.Zn7&[\ȰK'[G;wJ:(AkA$zIԺQZgIQQV{]=Uϭ;mǝkn"GSX2B\rcBb^5zڨ}i=׽Nz gU'FSa(:ÀΤ}4>Jjf.?OtI;d i' G|HUi9mQ^=: O0 Wwu8<:u;NujȽ묃Hl+ ?Φg!~H2Y_CN<|ގNlb=]]qtg)Fr TSC21Z(иu;UWh>:p80 OKq:U-) e|u3ܪ*lu O񚅸&Y3fIf'lNPr-G6mʪCc@u OoOJ_oRSqZ<H$HS,wz/`>ReW_n%䚶# QTg9- On}UKHm債t'e%OJ[<)|b`g_Bg/Ҥֿ*lf=XV <<{V4<%Ҥv&N΢dκ1"=6t{R O9]?o>4.1HwC5Q>:2@7CGƴ޽Q#k?|4:Jn`uh tid!;.qf9z;:[ڊW tybUX#VIh2xBc3iH1=qpUo_gGq6E"DKAүBnq!jʒrZyu3X % OfqϮ\}{b҇lliW*~\aDd0hxJ V= 7BToK[%\._DWRׂ{@qA)b@q%wI#r*ꍳ : O5_};:>[ZDʸsw b.;ADESbBЉA|dιUz6D] M9\HX܏{%O񜧄ai1Vzz5+v0a6wpg"1GSpF\r2ldwtkc4!""qn%VR'<NDDu,/p?,""7x8xu2+""g2P0 k#pY(y""fc?og](_s 9qݭփB^]cB9)^ DDDva?(oIĝ6a? Oj]9syQnUX)pk[DDDLvpn*""j whVԘ܋ T 0pm+4iDDD8c/k aJDDD:fhnn o|LDD$f3 s.ϴ*LDD4NLDDD"*a?*LckرjIENDB`rio/man/figures/logo.svg0000644000176200001440000106143714500615133014755 0ustar liggesusers image/svg+xml RIO rio/man/export_list.Rd0000644000176200001440000000457314476535676014521 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/export_list.R \name{export_list} \alias{export_list} \title{Export list of data frames to files} \usage{ export_list(x, file, archive = "", ...) } \arguments{ \item{x}{A list of data frames to be written to files.} \item{file}{A character vector string containing a single file name with a \verb{\\\%s} wildcard placeholder, or a vector of file paths for multiple files to be imported. If \code{x} elements are named, these will be used in place of \verb{\\\%s}, otherwise numbers will be used; all elements must be named for names to be used.} \item{archive}{character. Either empty string (default) to save files in current directory, a path to a (new) directory, or a .zip/.tar file to compress all files into an archive.} \item{\dots}{Additional arguments passed to \code{\link[=export]{export()}}.} } \value{ The name(s) of the output file(s) as a character vector (invisibly). } \description{ Use \code{\link[=export]{export()}} to export a list of data frames to a vector of file names or a filename pattern. } \details{ \code{\link[=export]{export()}} can export a list of data frames to a single multi-dataset file (e.g., an Rdata or Excel .xlsx file). Use \code{export_list} to export such a list to \emph{multiple} files. } \examples{ ## For demo, a temp. file path is created with the file extension .xlsx xlsx_file <- tempfile(fileext = ".xlsx") export( list( mtcars1 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars3 = mtcars[21:32, ] ), xlsx_file ) # import a single file from multi-object workbook import(xlsx_file, sheet = "mtcars1") # import all worksheets, the return value is a list import_list(xlsx_file) library('datasets') export(list(mtcars1 = mtcars[1:10,], mtcars2 = mtcars[11:20,], mtcars3 = mtcars[21:32,]), xlsx_file <- tempfile(fileext = ".xlsx") ) # import all worksheets list_of_dfs <- import_list(xlsx_file) # re-export as separate named files ## export_list(list_of_dfs, file = c("file1.csv", "file2.csv", "file3.csv")) # re-export as separate files using a name pattern; using the names in the list ## This will be written as "mtcars1.csv", "mtcars2.csv", "mtcars3.csv" ## export_list(list_of_dfs, file = "\%s.csv") } \seealso{ \code{\link[=import]{import()}}, \code{\link[=import_list]{import_list()}}, \code{\link[=export]{export()}} } rio/man/export.Rd0000644000176200001440000001636414500613454013442 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/export.R \name{export} \alias{export} \title{Export} \usage{ export(x, file, format, ...) } \arguments{ \item{x}{A data frame or matrix to be written into a file. Exceptions to this rule are that \code{x} can be a list of data frames if the output file format is an OpenDocument Spreadsheet (.ods, .fods), Excel .xlsx workbook, .Rdata file, or HTML file, or a variety of R objects if the output file format is RDS or JSON. See examples.) To export a list of data frames to multiple files, use \code{\link[=export_list]{export_list()}} instead.} \item{file}{A character string naming a file. Must specify \code{file} and/or \code{format}.} \item{format}{An optional character string containing the file format, which can be used to override the format inferred from \code{file} or, in lieu of specifying \code{file}, a file with the symbol name of \code{x} and the specified file extension will be created. Must specify \code{file} and/or \code{format}. Shortcuts include: \dQuote{,} (for comma-separated values), \dQuote{;} (for semicolon-separated values), \dQuote{|} (for pipe-separated values), and \dQuote{dump} for \code{\link[base:dump]{base::dump()}}.} \item{\dots}{Additional arguments for the underlying export functions. This can be used to specify non-standard arguments. See examples.} } \value{ The name of the output file as a character string (invisibly). } \description{ Write data.frame to a file } \details{ This function exports a data frame or matrix into a file with file format based on the file extension (or the manually specified format, if \code{format} is specified). The output file can be to a compressed directory, simply by adding an appropriate additional extensiont to the \code{file} argument, such as: \dQuote{mtcars.csv.tar}, \dQuote{mtcars.csv.zip}, or \dQuote{mtcars.csv.gz}. \code{export} supports many file formats. See the documentation for the underlying export functions for optional arguments that can be passed via \code{...} \itemize{ \item Comma-separated data (.csv), using \code{\link[data.table:fwrite]{data.table::fwrite()}} \item Pipe-separated data (.psv), using \code{\link[data.table:fwrite]{data.table::fwrite()}} \item Tab-separated data (.tsv), using \code{\link[data.table:fwrite]{data.table::fwrite()}} \item SAS (.sas7bdat), using \code{\link[haven:write_sas]{haven::write_sas()}}. \item SAS XPORT (.xpt), using \code{\link[haven:read_xpt]{haven::write_xpt()}}. \item SPSS (.sav), using \code{\link[haven:read_spss]{haven::write_sav()}} \item SPSS compressed (.zsav), using \code{\link[haven:read_spss]{haven::write_sav()}} \item Stata (.dta), using \code{\link[haven:read_dta]{haven::write_dta()}}. Note that variable/column names containing dots (.) are not allowed and will produce an error. \item Excel (.xlsx), using \code{\link[writexl:write_xlsx]{writexl::write_xlsx()}}. \code{x} can also be a list of data frames; the list entry names are used as sheet names. \item R syntax object (.R), using \code{\link[base:dput]{base::dput()}} (by default) or \code{\link[base:dump]{base::dump()}} (if \code{format = 'dump'}) \item Saved R objects (.RData,.rda), using \code{\link[base:save]{base::save()}}. In this case, \code{x} can be a data frame, a named list of objects, an R environment, or a character vector containing the names of objects if a corresponding \code{envir} argument is specified. \item Serialized R objects (.rds), using \code{\link[base:readRDS]{base::saveRDS()}}. In this case, \code{x} can be any serializable R object. \item Serialized R objects (.qs), using \code{\link[qs:qsave]{qs::qsave()}}, which is significantly faster than .rds. This can be any R object (not just a data frame). \item "XBASE" database files (.dbf), using \code{\link[foreign:write.dbf]{foreign::write.dbf()}} \item Weka Attribute-Relation File Format (.arff), using \code{\link[foreign:write.arff]{foreign::write.arff()}} \item Fixed-width format data (.fwf), using \code{\link[utils:write.table]{utils::write.table()}} with \code{row.names = FALSE}, \code{quote = FALSE}, and \code{col.names = FALSE} \item gzip comma-separated data (.csv.gz), using \code{\link[utils:write.table]{utils::write.table()}} with \code{row.names = FALSE} \item \href{https://github.com/csvy}{CSVY} (CSV with a YAML metadata header) using \code{\link[data.table:fwrite]{data.table::fwrite()}}. \item Apache Arrow Parquet (.parquet), using \code{\link[arrow:write_parquet]{arrow::write_parquet()}} \item Feather R/Python interchange format (.feather), using \code{\link[arrow:write_feather]{arrow::write_feather()}} \item Fast storage (.fst), using \code{\link[fst:write_fst]{fst::write.fst()}} \item JSON (.json), using \code{\link[jsonlite:fromJSON]{jsonlite::toJSON()}}. In this case, \code{x} can be a variety of R objects, based on class mapping conventions in this paper: \url{https://arxiv.org/abs/1403.2805}. \item Matlab (.mat), using \code{\link[rmatio:write.mat-methods]{rmatio::write.mat()}} \item OpenDocument Spreadsheet (.ods, .fods), using \code{\link[readODS:write_ods]{readODS::write_ods()}} or \code{\link[readODS:write_ods]{readODS::write_fods()}}. \item HTML (.html), using a custom method based on \code{\link[xml2:xml_replace]{xml2::xml_add_child()}} to create a simple HTML table and \code{\link[xml2:write_xml]{xml2::write_xml()}} to write to disk. \item XML (.xml), using a custom method based on \code{\link[xml2:xml_replace]{xml2::xml_add_child()}} to create a simple XML tree and \code{\link[xml2:write_xml]{xml2::write_xml()}} to write to disk. \item YAML (.yml), using \code{\link[yaml:write_yaml]{yaml::write_yaml()}}, default to write the content with UTF-8. Might not work on some older systems, e.g. default Windows locale for R <= 4.2. \item Clipboard export (on Windows and Mac OS), using \code{\link[utils:write.table]{utils::write.table()}} with \code{row.names = FALSE} } When exporting a data set that contains label attributes (e.g., if imported from an SPSS or Stata file) to a plain text file, \code{\link[=characterize]{characterize()}} can be a useful pre-processing step that records value labels into the resulting file (e.g., \code{export(characterize(x), "file.csv")}) rather than the numeric values. Use \code{\link[=export_list]{export_list()}} to export a list of dataframes to separate files. } \examples{ ## For demo, a temp. file path is created with the file extension .csv csv_file <- tempfile(fileext = ".csv") ## .xlsx xlsx_file <- tempfile(fileext = ".xlsx") ## create CSV to import export(iris, csv_file) ## You can certainly export your data with the file name, which is not a variable: ## import(mtcars, "car_data.csv") ## pass arguments to the underlying function ## data.table::fwrite is the underlying function and `col.names` is an argument export(iris, csv_file, col.names = FALSE) ## export a list of data frames as worksheets export(list(a = mtcars, b = iris), xlsx_file) # NOT RECOMMENDED ## specify `format` to override default format export(iris, xlsx_file, format = "csv") ## That's confusing ## You can also specify only the format; in the following case ## "mtcars.dta" is written [also confusing] ## export(mtcars, format = "stata") } \seealso{ \code{\link[=characterize]{characterize()}}, \code{\link[=import]{import()}}, \code{\link[=convert]{convert()}}, \code{\link[=export_list]{export_list()}} } rio/DESCRIPTION0000644000176200001440000000717114502301742012555 0ustar liggesusersPackage: rio Type: Package Title: A Swiss-Army Knife for Data I/O Version: 1.0.1 Authors@R: c(person("Jason", "Becker", role = "aut", email = "jason@jbecker.co"), person("Chung-hong", "Chan", role = c("aut", "cre"), email = "chainsawtiney@gmail.com", comment = c(ORCID = "0000-0002-6232-7530")), person("David", "Schoch", email = "david@schochastics.net", role = c("aut"), comment = c(ORCID = "0000-0003-2952-4812")), person("Geoffrey CH", "Chan", role = "ctb", email = "gefchchan@gmail.com"), person("Thomas J.", "Leeper", role = "aut", email = "thosjleeper@gmail.com", comment = c(ORCID = "0000-0003-4097-6326")), person("Christopher", "Gandrud", role = "ctb"), person("Andrew", "MacDonald", role = "ctb"), person("Ista", "Zahn", role = "ctb"), person("Stanislaus", "Stadlmann", role = "ctb"), person("Ruaridh", "Williamson", role = "ctb", email = "ruaridh.williamson@gmail.com"), person("Patrick", "Kennedy", role = "ctb"), person("Ryan", "Price", email = "ryapric@gmail.com", role = "ctb"), person("Trevor L", "Davis", email = "trevor.l.davis@gmail.com", role = "ctb"), person("Nathan", "Day", email = "nathancday@gmail.com", role = "ctb"), person("Bill", "Denney", email="wdenney@humanpredictions.com", role="ctb", comment=c(ORCID="0000-0002-5759-428X")), person("Alex", "Bokov", email = "alex.bokov@gmail.com", role = "ctb", comment=c(ORCID="0000-0002-0511-9815")) ) Description: Streamlined data import and export by making assumptions that the user is probably willing to make: 'import()' and 'export()' determine the data structure from the file extension, reasonable defaults are used for data import and export (e.g., 'stringsAsFactors=FALSE'), web-based import is natively supported (including from SSL/HTTPS), compressed files can be read directly without explicit decompression, and fast import packages are used where appropriate. An additional convenience function, 'convert()', provides a simple method for converting between file types. URL: https://github.com/gesistsa/rio BugReports: https://github.com/gesistsa/rio/issues Depends: R (>= 3.6) Imports: tools, stats, utils, foreign, haven (>= 1.1.2), curl (>= 0.6), data.table (>= 1.11.2), readxl (>= 0.1.1), tibble, stringi, writexl, lifecycle, R.utils Suggests: datasets, bit64, testthat, knitr, magrittr, clipr, fst, hexView, jsonlite, pzfx, readODS (>= 2.1.0), readr, rmarkdown, rmatio, xml2 (>= 1.2.0), yaml, qs, arrow (>= 0.17.0) License: GPL-2 VignetteBuilder: knitr Encoding: UTF-8 RoxygenNote: 7.2.3 NeedsCompilation: no Packaged: 2023-09-19 10:00:11 UTC; chainsawriot Author: Jason Becker [aut], Chung-hong Chan [aut, cre] (), David Schoch [aut] (), Geoffrey CH Chan [ctb], Thomas J. Leeper [aut] (), Christopher Gandrud [ctb], Andrew MacDonald [ctb], Ista Zahn [ctb], Stanislaus Stadlmann [ctb], Ruaridh Williamson [ctb], Patrick Kennedy [ctb], Ryan Price [ctb], Trevor L Davis [ctb], Nathan Day [ctb], Bill Denney [ctb] (), Alex Bokov [ctb] () Maintainer: Chung-hong Chan Repository: CRAN Date/Publication: 2023-09-19 11:20:02 UTC rio/build/0000755000176200001440000000000014502270453012144 5ustar liggesusersrio/build/vignette.rds0000644000176200001440000000052014502270453014500 0ustar liggesusersRMO1-򩠑So@bB׺lCݴ5m"NwۥpC33}}"(MZLta `OˤJ oLF#l\\( RF@OsU4 GCbH;qĔX3V$ۑ-ëܟ<q骉x!/ 7IZGfA Ouz$=6#&Z}*>纊OCjfXՇjL m0@*I?z0]rB†&HVw[ޜIWsVY x<~_v bBG2{P/2Lrio/tests/0000755000176200001440000000000014476051106012211 5ustar liggesusersrio/tests/testthat/0000755000176200001440000000000014502301742014043 5ustar liggesusersrio/tests/testthat/test_format_dta.R0000644000176200001440000000213514500375101017344 0ustar liggesuserscontext("Stata (.dta) imports/exports") require("datasets") test_that("Export to Stata", { expect_true(export(mtcars, "mtcars.dta") %in% dir()) mtcars3 <- mtcars names(mtcars3)[1] <- "foo.bar" expect_error(export(mtcars3, "mtcars3.dta"), label = "Export fails on invalid Stata names") }) test_that("Import from Stata (read_dta)", { expect_true(is.data.frame(import("mtcars.dta"))) # arguments ignored expect_error(import("mtcars.dta", extraneous.argument = TRUE), NA) expect_silent(import("mtcars.dta", extraneous.argument = TRUE )) }) test_that("Import from Stata with extended Haven features (read_dta)", { expect_true(is.data.frame(mtcars_wtam <- import("mtcars.dta", col_select = c("wt", "am"), n_max = 10 ))) expect_identical(c(10L, 2L), dim(mtcars_wtam)) expect_identical(c("wt", "am"), names(mtcars_wtam)) }) test_that("haven is deprecated", { lifecycle::expect_deprecated(import("mtcars.dta", haven = TRUE)) lifecycle::expect_deprecated(import("mtcars.dta", haven = FALSE)) }) unlink("mtcars.dta") unlink("mtcars3.dta") rio/tests/testthat/test_format_arff.R0000644000176200001440000000040114047423624017516 0ustar liggesuserscontext("Weka (.arff) imports/exports") require("datasets") test_that("Export to Weka", { expect_true(export(iris, "iris.arff") %in% dir()) }) test_that("Import from Weka", { expect_true(is.data.frame(import("iris.arff"))) }) unlink("iris.arff") rio/tests/testthat/test_create_outfiles.R0000644000176200001440000000177614500016150020407 0ustar liggesuserstest_that(".create_outfiles works", { x <- list( a = data.frame(), b = data.frame(), c = data.frame() ) y <- list( data.frame(), data.frame(), data.frame() ) expect_identical(.create_outfiles("d_%s.csv", x), c("d_a.csv", "d_b.csv", "d_c.csv")) expect_identical(.create_outfiles("d_%s.csv", y), c("d_1.csv", "d_2.csv", "d_3.csv")) expect_identical(.create_outfiles(c("a.csv", "b.csv", "c.csv"), x), c("a.csv", "b.csv", "c.csv")) }) test_that(".create_outfiles errors", { x <- list( a = data.frame(), a = data.frame(), c = data.frame() ) y <- list( a = data.frame(), b = data.frame(), data.frame() ) expect_error(.create_outfiles("d_%s.csv", x)) expect_error(.create_outfiles(c("a.csv", "a.csv", "c.csv"), x)) expect_error(.create_outfiles(c("a.csv", "b.csv"), x)) expect_error(.create_outfiles(c("a.csv"), x)) expect_error(.create_outfiles(c("d_%s.csv"), y)) }) rio/tests/testthat/test_format_syd.R0000644000176200001440000000033114047423624017401 0ustar liggesuserscontext("Systat (.syd) imports/exports") test_that("Import from Systat", { skip_if_not_installed("foreign") expect_true(inherits(import(system.file("files/Iris.syd", package="foreign")[1]), "data.frame")) }) rio/tests/testthat/test_format_psv.R0000644000176200001440000000064214500271271017410 0ustar liggesuserscontext("PSV imports/exports") require("datasets") test_that("Export to PSV", { expect_true(export(iris, "iris.psv") %in% dir()) }) test_that("Import from PSV", { expect_true(is.data.frame(import("iris.psv"))) }) test_that("fread is deprecated", { lifecycle::expect_deprecated(import("iris.psv", fread = TRUE)) lifecycle::expect_deprecated(import("iris.psv", fread = FALSE)) }) unlink("iris.psv") rio/tests/testthat/test_import_list.R0000644000176200001440000001346514502270161017603 0ustar liggesuserscontext("Test import_list()") library("datasets") export(list(mtcars = mtcars, iris = iris), "data.rdata") export(mtcars, "mtcars.rds") test_that("Data identical (import_list)", { expect_equivalent(import_list(rep("mtcars.rds", 2)), list(mtcars, mtcars)) mdat <- rbind(mtcars, mtcars) dat <- import_list(rep("mtcars.rds", 2), rbind = TRUE) expect_true(ncol(dat) == ncol(mdat) + 1) expect_true(nrow(dat) == nrow(mdat)) expect_true("_file" %in% names(dat)) }) test_that("Import multi-object .Rdata in import_list()", { dat <- import_list("data.rdata") expect_true(identical(dat[[1]], mtcars)) expect_true(identical(dat[[2]], iris)) }) test_that("Import multiple HTML tables in import_list()", { dat <- import_list("../testdata/twotables.html") expect_true(identical(dim(dat[[1]]), dim(mtcars))) expect_true(identical(names(dat[[1]]), names(mtcars))) expect_true(identical(dim(dat[[2]]), dim(iris))) expect_true(identical(names(dat[[2]]), names(iris))) }) test_that("Import multiple HTML tables in import_list() but with htm #350", { temphtm <- tempfile(fileext = ".htm") file.copy("../testdata/twotables.html", temphtm) dat <- import_list(temphtm) expect_true(identical(dim(dat[[1]]), dim(mtcars))) expect_true(identical(names(dat[[1]]), names(mtcars))) expect_true(identical(dim(dat[[2]]), dim(iris))) expect_true(identical(names(dat[[2]]), names(iris))) }) test_that("import_list() preserves 'which' names when specified", { export(list(a = mtcars, b = iris), "foo.xlsx") expect_true(identical(names(import_list("foo.xlsx")), c("a", "b"))) expect_true(identical(names(import_list("foo.xlsx", which = 1)), "a")) expect_true(identical(names(import_list("foo.xlsx", which = "a")), "a")) expect_true(identical(names(import_list("foo.xlsx", which = 2)), "b")) expect_true(identical(names(import_list("foo.xlsx", which = "b")), "b")) expect_true(identical(names(import_list("foo.xlsx", which = 1:2)), c("a", "b"))) expect_true(identical(names(import_list("foo.xlsx", which = 2:1)), c("b", "a"))) expect_true(identical(names(import_list("foo.xlsx", which = c("a", "b"))), c("a", "b"))) expect_true(identical(names(import_list("foo.xlsx", which = c("b", "a"))), c("b", "a"))) unlink("foo.xlsx") }) test_that("Import single file via import_list()", { expect_true(identical(import_list("mtcars.rds", rbind = TRUE), mtcars)) }) test_that("Import single file from zip via import_list()", { export(mtcars, "mtcars.csv.zip", format = "csv") expect_true(inherits(import_list("mtcars.csv.zip")[[1L]], "data.frame")) expect_true(inherits(import_list("mtcars.csv.zip", which = 1)[[1L]], "data.frame")) expect_true(inherits(import_list("mtcars.csv.zip", which = "mtcars.csv")[[1L]], "data.frame")) }) test_that("Using setclass in import_list()", { dat1 <- import_list(rep("mtcars.rds", 2), setclass = "data.table", rbind = TRUE) expect_true(inherits(dat1, "data.table")) dat2 <- import_list(rep("mtcars.rds", 2), setclass = "tbl", rbind = TRUE) expect_true(inherits(dat2, "tbl")) }) test_that("Object names are preserved by import_list()", { export(list(mtcars1 = mtcars[1:10,], mtcars2 = mtcars[11:20,], mtcars3 = mtcars[21:32,]), "mtcars.xlsx") export(mtcars[1:10,], "mtcars1.csv") export(mtcars[11:20,], "mtcars2.tsv") export(mtcars[21:32,], "mtcars3.csv") expected_names <- c("mtcars1", "mtcars2", "mtcars3") dat_xls <- import_list("mtcars.xlsx") dat_csv <- import_list(c("mtcars1.csv","mtcars2.tsv","mtcars3.csv")) expect_identical(names(dat_xls), expected_names) expect_identical(names(dat_csv), expected_names) unlink(c("mtcars.xlsx", "mtcars1.csv","mtcars2.tsv","mtcars3.csv")) }) test_that("File names are added as attributes by import_list()", { export(mtcars[1:10,], "mtcars.csv") export(mtcars[11:20,], "mtcars.tsv") expected_names <- c("mtcars", "mtcars") expected_attrs <- c(mtcars = "mtcars.csv", mtcars = "mtcars.tsv") dat <- import_list(c("mtcars.csv","mtcars.tsv")) expect_identical(names(dat), expected_names) expect_identical(unlist(lapply(dat, attr, "filename")), expected_attrs) unlink(c("mtcars.csv", "mtcars.tsv")) }) test_that("URL #294", { skip_on_cran() ## url <- "https://evs.nci.nih.gov/ftp1/CDISC/SDTM/SDTM%20Terminology.xls" That's 10MB! url <- "https://github.com/tidyverse/readxl/raw/main/tests/testthat/sheets/sheet-xml-lookup.xlsx" expect_error(x <- import_list(url), NA) expect_true(inherits(x, "list")) expect_true("Asia" %in% names(x)) expect_true("Africa" %in% x[[1]]$continent) expect_false("Africa" %in% x[[2]]$continent) ## double URLs; it reads twice the first sheet by default urls <- c(url, url) expect_error(x2 <- import_list(urls), NA) expect_true("sheet-xml-lookup" %in% names(x2)) expect_true("Africa" %in% x2[[1]]$continent) expect_true("Africa" %in% x2[[2]]$continent) }) test_that("Universal dummy `which` #326", { formats <- c("xlsx", "dta", "sav", "csv", "csv2") for (format in formats) { tempzip <- tempfile(fileext = paste0(".", format, ".zip")) rio::export(mtcars, tempzip, format = format) expect_warning(rio::import(tempzip), NA) expect_warning(rio::import_list(tempzip), NA) } }) test_that("Universal dummy `which` (Suggests) #326", { skip_if_not_installed("qs") skip_if_not_installed("arrow") skip_if_not_installed("readODS") formats <- c("qs", "parquet", "ods") for (format in formats) { tempzip <- tempfile(fileext = paste0(".", format, ".zip")) rio::export(mtcars, tempzip, format = format) expect_warning(rio::import(tempzip), NA) expect_warning(rio::import_list(tempzip), NA) } }) unlink("data.rdata") unlink("mtcars.rds") unlink("mtcars.csv.zip") rio/tests/testthat/test_format_sas.R0000644000176200001440000000072114476051106017371 0ustar liggesuserscontext("SAS imports/exports") require("datasets") #test_that("Import from SAS (.sas7bdat)", {}) test_that("Export SAS (.xpt)", { expect_true(export(mtcars, "mtcars.xpt") %in% dir()) }) test_that("Import from SAS (.xpt)", { expect_true(inherits(import("mtcars.xpt"), "data.frame")) }) test_that("Export SAS (.sas7bdat)", { expect_true(suppressWarnings(export(mtcars, "mtcars.sas7bdat")) %in% dir()) }) unlink("mtcars.sas7bdat") unlink("mtcars.xpt") rio/tests/testthat/test_format_feather.R0000644000176200001440000000056014502270161020214 0ustar liggesuserscontext("feather imports/exports") skip_if_not_installed("arrow") require("datasets") test_that("Export to feather", { skip_if_not_installed("arrow") expect_true(export(iris, "iris.feather") %in% dir()) }) test_that("Import from feather", { skip_if_not_installed("arrow") expect_true(is.data.frame(import("iris.feather"))) }) unlink("iris.feather") rio/tests/testthat/test_format_pzfx.R0000644000176200001440000000152714500375101017567 0ustar liggesuserscontext("pzfx imports/exports") require("datasets") iris_numeric <- iris iris_numeric$Species <- as.numeric(iris_numeric$Species) test_that("Export to pzfx", { skip_if_not_installed(pkg="pzfx") expect_true(export(iris_numeric, "iris.pzfx") %in% dir()) }) test_that("Import from pzfx", { skip_if_not_installed(pkg="pzfx") expect_true(is.data.frame(import("iris.pzfx"))) # Note that the dim test is only true as long as the data are exported with # write_pzfx(..., row_names=FALSE) which is the default in the export # method, but it is not default in pzfx::write_pzfx() expect_true(identical(dim(import("iris.pzfx")), dim(iris_numeric))) expect_true(identical(dim(import("iris.pzfx", which = "Data 1")), dim(iris_numeric))) expect_true(identical(dim(import("iris.pzfx", table = "Data 1")), dim(iris_numeric))) }) unlink("iris.pzfx") rio/tests/testthat/test_format_eviews.R0000644000176200001440000000030614047423624020106 0ustar liggesuserscontext("EViews import") test_that("Import from EViews", { skip_if_not_installed(pkg="hexView") expect_true(is.data.frame(suppressWarnings(import(hexView::hexViewFile("data4-1.wf1"))))) }) rio/tests/testthat/test_guess.R0000644000176200001440000000226514476631364016400 0ustar liggesuserscontext("Get File Extension") library("datasets") test_that("File extension converted correctly", { expect_that(get_ext("hello.csv"), equals("csv")) expect_that(get_ext("hello.CSV"), equals("csv")) expect_that(get_ext("hello.sav.CSV"), equals("csv")) expect_that(get_ext("clipboard"), equals("clipboard")) expect_error(get_ext(1L)) }) test_that("Format converted correctly", { expect_that(.standardize_format(","), equals("csv")) expect_that(.standardize_format(";"), equals("csv2")) expect_that(.standardize_format("|"), equals("psv")) expect_that(.standardize_format("\t"), equals("tsv")) expect_that(.standardize_format("excel"), equals("xlsx")) expect_that(.standardize_format("stata"), equals("dta")) expect_that(.standardize_format("spss"), equals("sav")) expect_that(.standardize_format("sas"), equals("sas7bdat")) }) test_that("Export without file specified", { expect_true(export(iris, format = "csv") %in% dir()) unlink("iris.csv") }) test_that(".check_pkg_availability", { expect_error(.check_pkg_availability("nonexistingpkg1233222"), "Suggested package `nonexisting") expect_error(.check_pkg_availability("rio"), NA) }) rio/tests/testthat/test_identical.R0000644000176200001440000000425514502270161017167 0ustar liggesuserscontext("Check Data Identical") test_that("Data identical (text formats)", { expect_equivalent(import(export(mtcars, "mtcars.txt")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.csv")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.tsv")), mtcars) }) unlink("mtcars.txt") unlink("mtcars.csv") unlink("mtcars.tsv") test_that("Data identical (R formats)", { expect_equivalent(import(export(mtcars, "mtcars.rds")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.R")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.RData")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.R", format = "dump")), mtcars) }) unlink("mtcars.rds") unlink("mtcars.R") unlink("mtcars.RData") test_that("Data identical (R formats), feather", { skip_if_not_installed("arrow") expect_equivalent(import(export(mtcars, "mtcars.feather")), mtcars) unlink("mtcars.feather") }) test_that("Data identical (haven formats)", { expect_equivalent(import(export(mtcars, "mtcars.dta")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.sav")), mtcars) }) unlink("mtcars.dta") unlink("mtcars.sav") test_that("Data identical (Excel formats)", { expect_equivalent(import(export(mtcars, "mtcars.xlsx")), mtcars) }) unlink("mtcars.xlsx") test_that("Data identical (other formats)", { expect_equivalent(import(export(mtcars, "mtcars.dbf")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.json")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.arff")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.xml")), mtcars) }) unlink("mtcars.dbf") unlink("mtcars.json") unlink("mtcars.arff") unlink("mtcars.xml") test_that("Data identical (optional arguments)", { #expect_equivalent(import(export(mtcars, "mtcars.csv", format = "csv2"), format = "csv2"), mtcars) expect_equivalent(import(export(mtcars, "mtcars.csv"), nrows = 4), mtcars[1:4,]) expect_equivalent(import(export(mtcars, "mtcars.csv", format = "tsv"), format = "tsv"), mtcars) expect_true(all.equal(import(export(mtcars, "mtcars", format = "csv"), format = "csv"), mtcars, check.attributes = FALSE)) }) unlink("mtcars.csv") unlink("mtcars") rio/tests/testthat/test_format_sav.R0000644000176200001440000000516314500271271017374 0ustar liggesuserscontext("SPSS (.sav) imports/exports") require("datasets") mtcars2 <- mtcars # label and value labels mtcars2[["cyl"]] <- factor(mtcars2[["cyl"]], c(4, 6, 8), c("four", "six", "eight")) attr(mtcars2[["cyl"]], "label") <- "cylinders" # value labels only mtcars2[["am"]] <- factor(mtcars2[["am"]], c(0, 1), c("automatic", "manual")) # variable label only attr(mtcars2[["mpg"]], "label") <- "miles per gallon" test_that("Export to SPSS (.sav)", { expect_true(export(mtcars2, "mtcars.sav") %in% dir()) }) test_that("Export to SPSS compressed (.zsav)", { expect_true(export(mtcars2, "mtcars.zsav") %in% dir()) }) test_that("Import from SPSS (.sav; read_sav)", { expect_true(d <- is.data.frame(import("mtcars.sav"))) expect_true(!"labelled" %in% unlist(lapply(d, class))) rm(d) }) test_that("Import from SPSS (.zsav; read_sav)", { expect_true(d <- is.data.frame(import("mtcars.zsav"))) expect_true(!"labelled" %in% unlist(lapply(d, class))) rm(d) }) test_that("Variable label and value labels preserved on SPSS (.sav) roundtrip", { d <- import("mtcars.sav") a_cyl <- attributes(d[["cyl"]]) expect_true("label" %in% names(a_cyl)) expect_true("labels" %in% names(a_cyl)) expect_true(identical(a_cyl[["label"]], "cylinders")) expect_true(identical(a_cyl[["labels"]], stats::setNames(c(1.0, 2.0, 3.0), c("four", "six", "eight")))) a_am <- attributes(d[["am"]]) expect_true("labels" %in% names(a_am)) expect_true(identical(a_am[["labels"]], stats::setNames(c(1.0, 2.0), c("automatic", "manual")))) a_mpg <- attributes(d[["mpg"]]) expect_true("label" %in% names(a_mpg)) expect_true(identical(a_mpg[["label"]], "miles per gallon")) }) test_that("Variable label and value labels preserved on SPSS compressed (.zsav) roundtrip", { d <- import("mtcars.zsav") a_cyl <- attributes(d[["cyl"]]) expect_true("label" %in% names(a_cyl)) expect_true("labels" %in% names(a_cyl)) expect_true(identical(a_cyl[["label"]], "cylinders")) expect_true(identical(a_cyl[["labels"]], stats::setNames(c(1.0, 2.0, 3.0), c("four", "six", "eight")))) a_am <- attributes(d[["am"]]) expect_true("labels" %in% names(a_am)) expect_true(identical(a_am[["labels"]], stats::setNames(c(1.0, 2.0), c("automatic", "manual")))) a_mpg <- attributes(d[["mpg"]]) expect_true("label" %in% names(a_mpg)) expect_true(identical(a_mpg[["label"]], "miles per gallon")) }) test_that("haven is deprecated", { lifecycle::expect_deprecated(import("mtcars.sav", haven = TRUE)) lifecycle::expect_deprecated(import("mtcars.sav", haven = FALSE)) }) unlink("mtcars.sav") unlink("mtcars.zsav") rio/tests/testthat/test_format_dbf.R0000644000176200001440000000064214476051106017340 0ustar liggesuserscontext("XBASE (.dbf) imports/exports") require("datasets") test_that("Export to XBASE (.dbf)", { skip_if_not_installed("foreign") expect_true(export(iris, "iris.dbf") %in% dir()) }) test_that("Import from XBASE (.dbf)", { skip_if_not_installed("foreign") d <- import("iris.dbf") expect_true(is.data.frame(d)) expect_true(!"factor" %in% vapply(d, class, character(1))) }) unlink("iris.dbf") rio/tests/testthat/test_format_parquet.R0000644000176200001440000000043214502270161020255 0ustar liggesuserscontext("Parquet imports/exports") require("datasets") test_that("Export to and import from parquet", { skip_if_not_installed("arrow") expect_true(export(iris, "iris.parquet") %in% dir()) expect_true(is.data.frame(import("iris.parquet"))) unlink("iris.parquet") }) rio/tests/testthat/test_format_dif.R0000644000176200001440000000032114047423624017343 0ustar liggesuserscontext("DIF imports/exports") test_that("Import from DIF", { dd <- import(file.path(system.file("misc", package = "utils"), "exDIF.dif"), transpose = TRUE) expect_true(inherits(dd, "data.frame")) }) rio/tests/testthat/test_format_matlab.R0000644000176200001440000000073414475527224020057 0ustar liggesuserscontext("rmatio imports/exports") require("datasets") test_that("Export to matlab", { skip("failing mysteriously") # skip_if_not_installed(pkg="rmatio") expect_true(export(iris, "iris.matlab") %in% dir()) }) test_that("Import from matlab", { skip("failing mysteriously") # skip_if_not_installed(pkg="rmatio") expect_true(is.data.frame(import("iris.matlab"))) expect_true(identical(dim(import("iris.matlab")), dim(iris))) }) unlink("iris.matlab") rio/tests/testthat/test_export_list.R0000644000176200001440000000427414476535676017641 0ustar liggesuserscontext("Test export_list()") library("datasets") export(list( mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ] ), "mtcars.xlsx") mylist <- import_list("mtcars.xlsx") test_that("export_list() works", { expect_error(export_list(mtcars), label = "export_list() fails on exporting single data frame") expect_error(export_list(mylist, file = NULL), label = "export_list() fails when file is NULL") expect_true(identical(export_list(mylist, file = paste0("mtcars_", 3:1, ".csv")), paste0("mtcars_", 3:1, ".csv"))) expect_true(identical(export_list(mylist, file = "%s.csv"), paste0("mtcars", 3:1, ".csv"))) expect_true(identical(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.zip"), "archive.zip")) expect_true(identical(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "arch/archive.zip"), "arch/archive.zip")) expect_true(all.equal(mylist[["mtcars1"]], import("mtcars1.csv"))) expect_true(all.equal(mylist[["mtcars2"]], import("mtcars2.csv"))) expect_true(all.equal(mylist[["mtcars3"]], import("mtcars3.csv"))) names(mylist) <- NULL expect_true(identical(export_list(mylist, file = "mtcars_%s.csv"), paste0("mtcars_", 1:3, ".csv"))) names(mylist) <- c("a", "", "c") expect_error(export_list(mylist), label = "export_list() fails without 'file' argument") expect_error(export_list(mylist, file = "%.csv"), label = "export_list() fails without missing names") expect_error(export_list(mylist, file = c("a.csv", "b.csv")), label = "export_list() fails with mismatched argument lengths") names(mylist) <- c("a", "a", "c") expect_error(export_list(mylist, file = "mtcars_%s.csv"), label = "export_list() fails with duplicated data frame names") expect_error(export_list(mylist, file = c("mtcars1.csv", "mtcars1.csv", "mtcars3.csv")), label = "export_list() fails with duplicated data frame names") }) unlink("mtcars.xlsx") unlink("mtcars1.csv") unlink("mtcars2.csv") unlink("mtcars3.csv") unlink("mtcars_1.csv") unlink("mtcars_2.csv") unlink("mtcars_3.csv") unlink("a.csv") unlink("b.csv") unlink("archive.zip") unlink("arch/archive.zip") unlink("arch/", recursive = TRUE) rio/tests/testthat/test_errors.R0000644000176200001440000000264114476631364016564 0ustar liggesuserscontext("Errors") library("datasets") test_that("Function suggestions for unsupported export", { expect_error(export(data.frame(1), "test.jpg"), "jpg format not supported. Consider using the 'jpeg::writeJPEG()' function", fixed = TRUE) }) test_that("Error for unsupported file types", { writeLines("123", con = "test.faketype") expect_error(import("test.faketype"), "Format not supported") expect_error(export(mtcars, "mtcars.faketype"), "Format not supported") expect_equal(.standardize_format("faketype"), "faketype") expect_error(get_ext("noextension"), "'file' has no extension") unlink("test.faketype") }) test_that("Error for mixed support file types", { expect_error(import("test.por"), "No such file") expect_error(export(mtcars, "mtcars.por"), "Format not supported") expect_error(export(mtcars, "mtcars.faketype"), "Format not supported") }) test_that("Only export data.frame or matrix", { expect_error(export(1, "test.csv"), "'x' is not a data.frame or matrix") }) test_that("Column widths printed for fixed-width format", { expect_true(is.character(export(data.frame(1), "test.txt", format = "fwf", verbose = FALSE))) expect_message(export(data.frame(1), "test.txt", format = "fwf", verbose = TRUE)) unlink("test.txt") }) test_that("Warning for import_list() with missing file", { expect_warning(import_list("fake_file.csv")) }) rio/tests/testthat/test_install_formats.R0000644000176200001440000000041014477067105020436 0ustar liggesuserscontext("Install uninstalled formats") test_that("uninstalled_formats()", { skip_on_cran() formats <- uninstalled_formats() if (is.null(formats)) { expect_true(install_formats()) } else { expect_type(formats, "character") } }) rio/tests/testthat/test_extensions.R0000644000176200001440000000123414047423624017434 0ustar liggesuserscontext("Extensions") library("datasets") test_that("S3 extension mechanism works for imports", { write.csv(iris, 'iris.custom') expect_error(import("iris.custom")) .import.rio_custom <- function(file, ...){ read.csv(file, ...) } #expect_true(is.data.frame(import('iris.custom'))) rm(.import.rio_custom) }) test_that("S3 extension mechanism works for exports", { expect_error(export("iris.custom")) .export.rio_custom <- function(file, data, ...){ write.csv(data, file, ...) invisible(file) } expect_error(is.character(export(iris, "iris.custom"))) rm(.export.rio_custom) }) unlink("iris.custom") rio/tests/testthat/test_format_fwf.R0000644000176200001440000000224114500271271017357 0ustar liggesuserscontext("FWF imports/exports") require("datasets") test_that("Export to FWF", { expect_true(export(iris, "iris.fwf") %in% dir()) expect_true(export(iris, "iris.txt", format = "fwf") %in% dir()) }) test_that("Import from FWF (read.fwf)", { expect_true(is.data.frame(import("iris.fwf", widths = c(3, 3, 3, 3, 1)))) expect_true(is.data.frame(import("iris.fwf", widths = list(c(3, 3, 3, 3, 1))))) expect_true(is.data.frame(import("iris.fwf", widths = c(3, 3, 3, 3, 1), col.names = names(iris)))) expect_true(is.data.frame(import("iris.txt", widths = c(3, 3, 3, 3, 1), format = "fwf"))) # negative column widths expect_true(is.data.frame(import("iris.fwf", widths = c(-3, 3, 3, 3, 1)))) }) test_that("Import from FWF Errors", { expect_error(import("iris.fwf"), "Import of fixed-width format data requires a 'widths' argument. See ? read.fwf().", fixed = TRUE ) }) test_that("readr is deprecated", { lifecycle::expect_deprecated(import("iris.fwf", widths = c(3, 3, 3, 3, 1), readr = TRUE)) lifecycle::expect_deprecated(import("iris.fwf", widths = c(3, 3, 3, 3, 1), readr = FALSE)) }) unlink("iris.fwf") unlink("iris.txt") rio/tests/testthat/test_gather_attrs.R0000644000176200001440000000342314047423624017726 0ustar liggesuserscontext("Gather attrs") e <- try(import("http://www.stata-press.com/data/r13/auto.dta")) if (!inherits(e, "try-error")) { g <- gather_attrs(e) test_that("Gather attrs from Stata", { expect_true(length(attributes(e[[1]])) >= 1) expect_true(length(attributes(g[[1]])) == 0) expect_true(length(attributes(e)) == 5) expect_true(length(attributes(g)) == 8) expect_true("label" %in% names(attributes(e[[1]]))) expect_true(!"label" %in% names(attributes(g[[1]]))) expect_true("label" %in% names(attributes(g))) expect_true("labels" %in% names(attributes(g))) expect_true("format.stata" %in% names(attributes(g))) expect_true(!"format.stata" %in% names(attributes(g[[1]]))) }) test_that("Spread attrs from Stata", { s <- spread_attrs(g) # df-level attributes expect_true("label" %in% names(attributes(s))) expect_true("notes" %in% names(attributes(s))) # spread attributes expect_true("format.stata" %in% names(attributes(s[[1]]))) expect_true(!"format.stata" %in% names(attributes(s))) expect_true("label" %in% names(attributes(s[[1]]))) expect_true(!"labels" %in% names(attributes(s))) }) test_that("Gather empty attributes", { require("datasets") g <- gather_attrs(iris) expect_true(length(attributes(iris[[1]])) == 0) expect_true(length(attributes(g[[1]])) == 0) expect_true(length(attributes(iris)) == 3) expect_true(length(attributes(g)) == 3) }) test_that("gather_attrs() fails on non-data frame", { expect_error(gather_attrs(letters)) }) test_that("spread_attrs() fails on non-data frame", { expect_error(spread_attrs(letters)) }) rm(e) } rio/tests/testthat/test_format_ods.R0000644000176200001440000000346514500613454017376 0ustar liggesuserscontext("ODS imports/exports") require("datasets") test_that("Import from ODS", { skip_if_not_installed(pkg="readODS") ods0 <- import("../testdata/mtcars.ods") expect_error(ods <- import("../testdata/mtcars.ods", sheet = 1, col_names = TRUE, invalid_argument = 42), NA) expect_identical(ods0, ods, label = "ODS import ignored arguments don't affect output") expect_true(is.data.frame(ods), label = "ODS import returns data.frame") expect_true(identical(names(mtcars), names(ods)), label = "ODS import returns correct names") expect_true(identical(dim(mtcars), dim(ods)), label = "ODS import returns correct dimensions") expect_equivalent(ods, mtcars, label = "ODS import returns correct values") }) test_that("Export to ODS", { skip_if_not_installed(pkg="readODS") expect_true(export(iris, "iris.ods") %in% dir()) }) test_that("... correctly passed #318", { skip_if_not_installed(pkg = "readODS") x <- tempfile(fileext = ".ods") rio::export(mtcars, file = x, sheet = "mtcars") expect_equal(readODS::list_ods_sheets(x), "mtcars") }) test_that("Export and Import FODS", { skip_if_not_installed(pkg = "readODS") x <- tempfile(fileext = ".fods") rio::export(mtcars, file = x, sheet = "mtcars") expect_equal(readODS::list_fods_sheets(x), "mtcars") expect_error(y <- import(x), NA) expect_true(is.data.frame(y)) }) test_that("Export list of data frames", { skip_if_not_installed(pkg = "readODS") dfs <- list("cars" = mtcars, "flowers" = iris) x1 <- tempfile(fileext = ".ods") x2 <- tempfile(fileext = ".fods") expect_error(export(dfs, x1), NA) expect_error(export(dfs, x2), NA) expect_equal(import(x1, which = "flowers"), import(x2, which = "flowers")) }) unlink("iris.ods") rio/tests/testthat/test_format_html.R0000644000176200001440000000440614476051113017551 0ustar liggesuserscontext("HTML imports/exports") require("datasets") test_html <- function(breaker = "&") { mtcars2 <- mtcars colnames(mtcars2)[1] <- paste0("mp", breaker, breaker, "g") mtcars2[1,1] <- paste0("mp", breaker, breaker, "g") expect_error(x <- rio::export(mtcars2, tempfile(fileext = ".html")), NA) temp_df <- rio::import(x) expect_equal(colnames(temp_df)[1], paste0("mp", breaker, breaker, "g")) expect_equal(temp_df[1,1], paste0("mp", breaker, breaker, "g")) } test_that("Export to HTML", { skip_if_not_installed("xml2") expect_true(export(iris, "iris.html") %in% dir(), label = "export to html works") }) test_that("Export to HTML with ampersands",{ skip_if_not_installed("xml2") iris$`R & D` <- paste(sample(letters,nrow(iris),rep=T), '&', sample(LETTERS,nrow(iris),rep=TRUE)) expect_true(export(iris, "iris2.html") %in% dir(), label = "export to html with ampersands works") }) test_that("Import from HTML", { skip_if_not_installed("xml2") expect_true(is.data.frame(import("iris.html")), label = "import from single-table html works") f <- "../testdata/twotables.html" expect_true(all(dim(import(f, which = 1)) == c(32, 11)), label = "import from two-table html works (which = 1)") expect_true(all(dim(import(f, which = 2)) == c(150, 5)), label = "import from two-table html works (which = 2)") }) test_that("Import from HTML with multiple tbody elements", { skip_if_not_installed("xml2") expect_true(is.data.frame(import("../testdata/two-tbody.html")), label="import with two tbody elements in a single html table works") expect_true(is.data.frame(import("../testdata/br-in-header.html")), label="import with an empty header cell in an html table works") expect_true(is.data.frame(import("../testdata/br-in-td.html")), label="import with an empty data cell in a single html table works") expect_true(is.data.frame(import("../testdata/th-as-row-element.html")), label="import with th instead of td in a non-header row in a single html table works") }) unlink(c("iris.xml", "iris2.xml", "iris2.html")) test_that("html with &, >, ', \", >, <", { skip_if_not_installed("xml2") ## test all useless <- lapply(c("&", "\"", "'", "<", ">"), test_html) }) rio/tests/testthat/test_format_xml.R0000644000176200001440000000204214476051113017377 0ustar liggesuserscontext("XML imports/exports") require("datasets") test_xml <- function(breaker = "&") { mtcars2 <- mtcars colnames(mtcars2)[1] <- paste0("mp", breaker, breaker, "g") mtcars2[1,1] <- paste0("mp", breaker, breaker, "g") expect_error(x <- rio::export(mtcars2, tempfile(fileext = ".xml")), NA) temp_df <- rio::import(x) expect_equal(colnames(temp_df)[1], paste0("mp..g")) expect_equal(temp_df[1,1], paste0("mp", breaker, breaker, "g")) } test_that("Export to XML", { skip_if_not_installed("xml2") #skip("temporarily skipping (https://github.com/r-lib/xml2/issues/339)") expect_true(export(iris, "iris.xml") %in% dir())}) test_that("Export to XML with &, >, ', \", >, <",{ skip_if_not_installed("xml2") ## test all useless <- lapply(c("&", "\"", "'", "<", ">"), test_xml) }) test_that("Import from XML", { skip_if_not_installed("xml2") skip("temporarily skipping (https://github.com/r-lib/xml2/issues/339)") expect_true(is.data.frame(import("iris.xml"))) }) unlink(c("iris.xml","iris2.xml")) rio/tests/testthat/test_export_corner_cases.R0000644000176200001440000000210414476340225021302 0ustar liggesuserstest_that("export to nonexisting directory #347", { output_dir <- file.path(tempdir(), "this_doesnt_exist") expect_false(dir.exists(output_dir)) expect_error(export(iris, file.path(output_dir, "iris.csv")), NA) expect_true(file.exists(file.path(output_dir, "iris.csv"))) unlink(output_dir, recursive = TRUE) }) test_that("export to existing directory (contra previous one) #347", { output_dir <- file.path(tempdir(), "this_surely_exists1") dir.create(output_dir, recursive = TRUE) expect_true(dir.exists(output_dir)) expect_error(export(iris, file.path(output_dir, "iris.csv")), NA) expect_true(file.exists(file.path(output_dir, "iris.csv"))) unlink(output_dir, recursive = TRUE) }) test_that("export to nonexisting directory also for compressed file #347", { output_dir <- file.path(tempdir(), "this_doesnt_exist") expect_false(dir.exists(output_dir)) expect_error(export(iris, file.path(output_dir, "iris.csv.gz")), NA) expect_true(file.exists(file.path(output_dir, "iris.csv.gz"))) unlink(output_dir, recursive = TRUE) }) rio/tests/testthat/test_format_yml.R0000644000176200001440000000140014476051106017377 0ustar liggesuserscontext("YAML imports/exports") require("datasets") test_that("Export to YAML", { skip_if_not_installed("yaml") expect_true(export(iris, "iris.yml") %in% dir()) }) test_that("Import from YAML", { skip_if_not_installed("yaml") expect_true(is.data.frame(import("iris.yml"))) expect_identical(import("iris.yml")[, 1:4], iris[, 1:4]) expect_identical(import("iris.yml")$Species, as.character(iris$Species)) }) test_that("utf-8", { skip_if(getRversion() <= "4.2") content <- c("\"", "\u010d", "\u0161", "\u00c4", "\u5b57", "\u30a2", "\u30a2\u30e0\u30ed") x <- data.frame(col = content) tempyaml <- tempfile(fileext = ".yaml") y <- import(export(x, tempyaml)) testthat::expect_equal(content, y$col) }) unlink("iris.yml") rio/tests/testthat/test_mapping.R0000644000176200001440000000247614500375101016667 0ustar liggesuserstest_that("mapping; both base and tidy conventions work", { tempxlsx <- tempfile(fileext = ".xlsx") export(list("mtcars" = mtcars, "iris" = iris), tempxlsx) expect_error(y <- import(tempxlsx, n_max = 42, sheet = "iris"), NA) expect_equal(nrow(y), 42) expect_error(y2 <- import(tempxlsx, n_max = 42, which = "iris"), NA) expect_equal(nrow(y2), 42) expect_equal(y, y2) expect_error(y <- import(tempxlsx, n_max = 42, col_names = FALSE, which = 2), NA) expect_equal(nrow(y), 42) expect_error(y2 <- import(tempxlsx, n_max = 42, header = FALSE, which = 2), NA) expect_equal(y, y2) }) test_that("Unused arguments are by default ignored silently", { tempxlsx <- tempfile(fileext = ".xlsx") export(list("mtcars" = mtcars, "iris" = iris), tempxlsx) expect_error(y <- import(tempxlsx, n_max = 42, whatever = TRUE, sheet = 2), NA) }) test_that("Unused arguments with option", { tempxlsx <- tempfile(fileext = ".xlsx") export(list("mtcars" = mtcars, "iris" = iris), tempxlsx) expect_error(R.utils::withOptions({ y <- import(tempxlsx, n_max = 42, whatever = TRUE) }, rio.ignoreunusedargs = FALSE)) expect_error(R.utils::withOptions({ y <- import(tempxlsx, n_max = 42, sheet = 2, whatever = TRUE) }, rio.ignoreunusedargs = FALSE), "whatever") ## not sheet }) rio/tests/testthat/test_matrix.R0000644000176200001440000000073314047423624016544 0ustar liggesuserscontext("Matrix imports/exports") require("datasets") test_that("Export matrix to CSV", { expect_true(export(warpbreaks, "temp1.csv") %in% dir()) expect_true(export(as.matrix(warpbreaks), "temp2.csv") %in% dir()) }) test_that("Import from matrix export", { expect_true(identical(import("temp1.csv", colClasses = rep("character", 3)), import("temp2.csv", colClasses = rep("character", 3)))) }) unlink("temp1.csv") unlink("temp2.csv") rio/tests/testthat/test_format_xls.R0000644000176200001440000000317614500375101017410 0ustar liggesuserscontext("Excel (xlsx) imports/exports") require("datasets") test_that("Export to Excel (.xlsx)", { expect_true(export(iris, "iris.xlsx") %in% dir()) }) test_that("Expert to Excel (.xlsx) a list", { tempxlsx <- tempfile(fileext = ".xlsx") export(list( mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ] ), tempxlsx) expect_equal(readxl::excel_sheets(tempxlsx), c("mtcars3", "mtcars2", "mtcars1")) }) test_that("Is `sheet` passed?", { tempxlsx <- tempfile(fileext = ".xlsx") export(list( mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ] ), tempxlsx) expect_equal(readxl::excel_sheets(tempxlsx), c("mtcars3", "mtcars2", "mtcars1")) content <- import(tempxlsx, sheet = "mtcars2") expect_equal(content$mpg, mtcars[11:20, ]$mpg) content <- import(tempxlsx, which = 2) expect_equal(content$mpg, mtcars[11:20, ]$mpg) }) test_that("readxl is deprecated", { lifecycle::expect_deprecated(import("iris.xlsx", readxl = TRUE)) lifecycle::expect_deprecated(import("iris.xlsx", readxl = FALSE)) }) test_that("Import from Excel (.xlsx)", { expect_true(is.data.frame(import("iris.xlsx", sheet = 1))) expect_true(is.data.frame(import("iris.xlsx", which = 1))) expect_true(nrow(import("iris.xlsx", n_max = 42)) == 42) }) test_that("Import from Excel (.xls)", { expect_true(is.data.frame(import("../testdata/iris.xls"))) expect_true(is.data.frame(import("../testdata/iris.xls", sheet = 1))) expect_true(is.data.frame(import("../testdata/iris.xls", which = 1))) }) unlink("iris.xlsx") rio/tests/testthat/test_format_rds.R0000644000176200001440000000074414500606254017376 0ustar liggesuserscontext("Rds imports/exports") require("datasets") test_that("Export to rds", { expect_true(export(iris, "iris.rds") %in% dir()) }) test_that("Import from rds", { expect_true(is.data.frame(import("iris.rds"))) }) test_that("Export to rds (non-data frame)", { expect_true(export(list(1:10, letters), "list.rds") %in% dir()) expect_true(inherits(import("list.rds"), "list")) expect_true(length(import("list.rds")) == 2L) }) unlink("iris.rds") unlink("list.rds") rio/tests/testthat/test_set_class.R0000644000176200001440000000514214502270161017207 0ustar liggesuserscontext("Set object class") library("datasets") mtcars_tibble <- tibble::as_tibble(mtcars) mtcars_datatable <- data.table::as.data.table(mtcars) test_that("Set object class", { expect_true(inherits(set_class(mtcars), "data.frame")) expect_true(inherits(set_class(mtcars_tibble), "data.frame")) expect_true(inherits(set_class(mtcars_datatable), "data.frame")) expect_true(inherits(set_class(mtcars, class = "fakeclass"), "data.frame")) expect_true(!"fakeclass" %in% class(set_class(mtcars, class = "fakeclass"))) }) test_that("Set object class as tibble", { expect_true(inherits(set_class(mtcars, class = "tbl_df"), "tbl_df")) expect_true(inherits(set_class(mtcars, class = "tibble"), "tbl_df")) expect_true(inherits(set_class(mtcars_tibble, class = "tibble"), "tbl_df")) }) test_that("Set object class as data.table", { expect_true(inherits(set_class(mtcars, class = "data.table"), "data.table")) export(mtcars, "mtcars.csv") expect_true(inherits(import("mtcars.csv", setclass = "data.table"), "data.table")) expect_true(inherits(import("mtcars.csv", data.table = TRUE, setclass = "data.table"), "data.table")) unlink("mtcars.csv") }) test_that("Set object class as arrow table", { skip_if(getRversion() <= "4.2") skip_if_not_installed("arrow") mtcars_arrow <- arrow::arrow_table(mtcars) expect_false(inherits(set_class(mtcars_arrow), "data.frame")) ## arrow table is not data.frame expect_true(inherits(set_class(mtcars, class = "arrow"), "ArrowTabular")) expect_true(inherits(set_class(mtcars, class = "arrow_table"), "ArrowTabular")) export(mtcars, "mtcars.csv") expect_true(inherits(import("mtcars.csv", setclass = "arrow"), "ArrowTabular")) expect_true(inherits(import("mtcars.csv", data.table = TRUE, setclass = "arrow"), "ArrowTabular")) unlink("mtcars.csv") }) test_that("ArrowTabular can be exported", { skip_if(getRversion() <= "4.2") skip_if_not_installed("arrow") mtcars_arrow <- arrow::arrow_table(mtcars) expect_error(export(mtcars_arrow, "mtcars.csv"), NA) ## no concept of rownames expect_true(inherits(import("mtcars.csv"), "data.frame")) unlink("mtcars.csv") }) test_that("Simulate arrow is not installed, #376", { ## although this is pretty meaningless with_mocked_bindings({ export(mtcars, "mtcars.csv") expect_error(import("mtcars.csv", setclass = "arrow"), "Suggested package") }, .check_pkg_availability = function(pkg, lib.loc = NULL) { stop("Suggested package `", pkg, "` is not available. Please install it individually or use `install_formats()`", call. = FALSE) }) }) rio/tests/testthat/test_characterize.R0000644000176200001440000000216614047423624017706 0ustar liggesuserscontext("characterize()/factorize()") x <- structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3)) xdf <- data.frame(v1 = structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3), label = "variable 1"), v2 = structure(c(1,0,0,1), labels = c("foo" = 0, "bar" = 1)), v3 = 4:1, label = "variable 2") test_that("test characterize.default()", { expect_true(identical(characterize(x), c(LETTERS[1:3], NA))) }) test_that("test characterize.default()", { expect_true(identical(characterize(xdf), {xdf[] <- lapply(xdf, characterize); xdf})) }) test_that("test factorize.data.frame()", { expect_true(identical(factorize(x), factor(x, attributes(x)$labels, names(attributes(x)$labels)))) }) test_that("test factorize.data.frame()", { expect_true(identical(factorize(xdf), {xdf[] <- lapply(xdf, factorize); xdf})) }) test_that("test factorize coerce_character", { expect_true(identical(letters[1:3], factorize(letters[1:3]))) expect_true( identical( factorize(letters[3:1], coerce_character = TRUE), factor(letters[3:1], levels = letters[1:3]) ) ) })rio/tests/testthat/test_format_external_packages.R0000644000176200001440000000135014047423624022264 0ustar liggesuserscontext("External package Import/Export support") require("datasets") test_that("External read functions without an import method", { extensions <- c("bib", "bmp", "gexf", "gnumeric", "jpeg", "jpg", "npy", "png", "sss", "sdmx", "tiff") for (ext in extensions) { file <- file.path(tempdir(), paste0("test.", ext)) file.create(file) on.exit(unlink(file)) expect_error(import(file)) } }) test_that("import method exported by an external package", { extensions <- c("bean", "beancount", "ledger", "hledger") for (ext in extensions) { file <- file.path(tempdir(), paste0("test.", ext)) file.create(file) on.exit(unlink(file)) expect_error(import(file)) } }) rio/tests/testthat/test_format_csv.R0000644000176200001440000000467014500415343017400 0ustar liggesuserscontext("CSV imports/exports") require("datasets") test_that("Export to CSV", { expect_true(export(iris, "iris.csv") %in% dir()) unlink("iris.csv") }) test_that("Export (Append) to CSV", { export(iris, "iris.csv") nlines <- length(readLines("iris.csv")) export(iris, "iris.csv", append = FALSE) expect_true(identical(length(readLines("iris.csv")), nlines)) export(iris, "iris.csv", append = TRUE) expect_true(identical(length(readLines("iris.csv")), (2L*nlines)-1L)) unlink("iris.csv") }) test_that("Import from CSV", { noheadercsv <- import("../testdata/noheader.csv", header = FALSE) expect_that(colnames(noheadercsv)[1], equals("V1"), label = "Header is correctly specified") }) test_that("Import from (European-style) CSV with semicolon separator", { write.table(iris, "iris2.csv", dec = ",", sep = ";", row.names = FALSE) expect_true("iris2.csv" %in% dir()) # import works (even if column classes are incorrect) expect_true(is.data.frame(import("iris2.csv", header = TRUE))) iris_imported <- import("iris2.csv", format = ";", header = TRUE) # import works with correct, numeric column classes expect_true(is.data.frame(iris_imported)) expect_true(is.numeric(iris_imported[["Sepal.Length"]])) }) context("CSV (.csv2) imports/exports") test_that("Export to CSV", { expect_true(export(iris, "iris.csv", format = "csv2") %in% dir()) }) test_that("Import from CSV (read.csv)", { expect_true(is.data.frame(import("iris.csv", format = "csv2"))) }) test_that("Import from CSV (fread)", { expect_true(is.data.frame(import("iris.csv", format = "csv2"))) }) test_that("Export to TSV with CSV extension", { expect_true(export(iris, "iris.csv", format = "tsv") %in% dir()) }) test_that("Import from TSV with CSV extension", { expect_true(ncol(import("iris.csv")) == 5L) expect_true(ncol(import("iris.csv", format = "tsv")) == 5L) expect_true(ncol(import("iris.csv", format = "tsv", sep = "\t")) == 5L) expect_true(ncol(import("iris.csv", sep = ",")) == 5L) # use `data.table::fread(sep = "auto")` even if `sep` set explicitly to "," expect_true(ncol(import("iris.csv", format = "csv")) == 5L) expect_true(ncol(import("iris.csv", sep = "auto")) == 5L) }) test_that("fread is deprecated", { lifecycle::expect_deprecated(import("iris.csv", fread = TRUE)) lifecycle::expect_deprecated(import("iris.csv", fread = FALSE)) }) unlink("iris.csv") unlink("iris2.csv") rio/tests/testthat/test_compress.R0000644000176200001440000000210514047423624017066 0ustar liggesuserscontext("Compressed files") test_that("Recognize compressed file types", { expect_true(rio:::find_compress("file.zip")$compress == "zip") expect_true(rio:::find_compress("file.tar")$compress == "tar") expect_true(rio:::find_compress("file.tar.gz")$compress == "tar") expect_true(is.na(rio:::find_compress("file.gz")$compress)) expect_true(is.na(rio:::find_compress("file.notcompressed")$compress)) }) test_that("Export to compressed (zip)", { e1 <- export(iris, "iris.csv.zip") expect_true(e1 %in% dir()) }) test_that("Export to compressed (tar)", { e2 <- export(iris, "iris.csv.tar") expect_true(e2 %in% dir()) }) test_that("Import from compressed", { expect_true(is.data.frame(import("iris.csv.zip"))) expect_true(is.data.frame(import("iris.csv.zip", which = 1))) expect_true(is.data.frame(import("iris.csv.zip", which = "iris.csv"))) # tar export does not work due to: https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=16716 #expect_true(is.data.frame(import("iris.csv.tar"))) }) unlink("iris.csv.zip") unlink("iris.csv.tar") rio/tests/testthat/test_format_fst.R0000644000176200001440000000047414047423624017406 0ustar liggesuserscontext("fst imports/exports") require("datasets") test_that("Export to fst", { skip_if_not_installed(pkg="fst") expect_true(export(iris, "iris.fst") %in% dir()) }) test_that("Import from fst", { skip_if_not_installed(pkg="fst") expect_true(is.data.frame(import("iris.fst"))) }) unlink("iris.fst") rio/tests/testthat/test_check_file.R0000644000176200001440000000465214476051106017316 0ustar liggesuserstest_that(".check_file", { data <- data.frame( x = sample(1:10, 10000, replace = TRUE), y = sample(1:10, 10000, replace = TRUE) ) expect_error(.check_file(1)) expect_error(.check_file(TRUE)) expect_error(.check_file(data)) expect_error(.check_file(iris)) expect_error(.check_file(c("a.csv", "b.csv"))) expect_error(.check_file("a.csv"), NA) expect_error(.check_file(), NA) ## single_only FALSE expect_error(.check_file(1, single_only = FALSE)) expect_error(.check_file(TRUE, single_only = FALSE)) expect_error(.check_file(data, single_only = FALSE)) expect_error(.check_file(iris, single_only = FALSE)) expect_error(.check_file(c("a.csv", "b.csv"), single_only = FALSE), NA) expect_error(.check_file("a.csv"), NA) expect_error(.check_file(single_only = FALSE), NA) }) test_that("Invalid file argument - import(), #301", { data <- data.frame( x = sample(1:10, 10000, replace = TRUE), y = sample(1:10, 10000, replace = TRUE) ) expect_error(import(data), "Invalid") expect_error(import(iris), "Invalid") expect_error(import(1), "Invalid") expect_error(import(TRUE), "Invalid") expect_error(import(c("a.csv", "b.csv")), "Invalid") }) test_that("Invalid file argument - import_list(), #301", { data <- data.frame( x = sample(1:10, 10000, replace = TRUE), y = sample(1:10, 10000, replace = TRUE) ) expect_error(import_list(data), "Invalid") expect_error(import_list(iris), "Invalid") expect_error(import_list(1), "Invalid") expect_error(import_list(TRUE), "Invalid") }) test_that("Invalid file argument - export(), #301", { data <- data.frame( x = sample(1:10, 10000, replace = TRUE), y = sample(1:10, 10000, replace = TRUE) ) expect_error(export(iris, data), "Invalid") expect_error(export(iris, iris), "Invalid") expect_error(export(iris, 1), "Invalid") expect_error(export(iris, TRUE), "Invalid") expect_error(export(iris, c("abc.csv", "123.csv")), "Invalid") }) test_that("Invalid file argument - export_list(), #301", { data <- data.frame( x = sample(1:10, 10000, replace = TRUE), y = sample(1:10, 10000, replace = TRUE) ) expect_error(export_list(iris, data), "Invalid") expect_error(export_list(iris, iris), "Invalid") expect_error(export_list(iris, 1), "Invalid") expect_error(export_list(iris, TRUE), "Invalid") }) rio/tests/testthat/test_remote.R0000644000176200001440000000401714476051106016530 0ustar liggesuserscontext("Remote Files") test_that("Import Remote Stata File", { f <- try(import("http://www.stata-press.com/data/r13/auto.dta")) if (!inherits(f, "try-error")) { expect_true(is.data.frame(f)) } }) test_that("Import Remote GitHub File", { rfile <- "https://raw.githubusercontent.com/leeper/rio/master/inst/examples/no_header.csv" rfile_imported1 <- try(import(rfile)) if (!inherits(rfile_imported1, "try-error")) { expect_true(inherits(rfile_imported1, "data.frame"), label = "Import remote file (implied format)") } rfile_imported2 <- try(import(rfile, format = "csv")) if (!inherits(rfile_imported2, "try-error")) { expect_true(inherits(rfile_imported2, "data.frame"), label = "Import remote file (explicit format)") } lfile <- remote_to_local(rfile) if (!inherits(lfile, "try-error")) { expect_true(file.exists(lfile), label = "Remote file copied successfully") expect_true(inherits(import(lfile), "data.frame"), label = "Import local copy successfully") } }) ## test_that("Import Remote File from Shortened URL", { ## skip_if_not_installed(pkg = "data.table") ## shorturl <- try(import("https://raw.githubusercontent.com/gesistsa/rio/main/tests/testdata/example.csvy")) ## if (!inherits(shorturl, "try-error")) { ## expect_true(inherits(shorturl, "data.frame"), label = "Import remote file") ## } ## }) test_that("Import from Google Sheets", { googleurl1 <- "https://docs.google.com/spreadsheets/d/1I9mJsS5QnXF2TNNntTy-HrcdHmIF9wJ8ONYvEJTXSNo/edit#gid=0" expect_true(inherits(import(googleurl1), "data.frame"), label = "Import google sheets (specified sheet)") googleurl2 <- "https://docs.google.com/spreadsheets/d/1I9mJsS5QnXF2TNNntTy-HrcdHmIF9wJ8ONYvEJTXSNo/edit" expect_true(inherits(import(googleurl2), "data.frame"), label = "Import google sheets (unspecified sheet)") expect_true(inherits(import(googleurl1, format = "tsv"), "data.frame"), label = "Import google sheets (specified sheet, specified format)") }) rio/tests/testthat/test_format_tsv.R0000644000176200001440000000064114500271271017413 0ustar liggesuserscontext("TSV imports/exports") require("datasets") test_that("Export to TSV", { expect_true(export(iris, "iris.tsv") %in% dir()) }) test_that("Import from TSV", { expect_true(is.data.frame(import("iris.tsv"))) }) test_that("fread is deprecated", { lifecycle::expect_deprecated(import("iris.tsv", fread = TRUE)) lifecycle::expect_deprecated(import("iris.tsv", fread = FALSE)) }) unlink("iris.tsv") rio/tests/testthat/test_format_qs.R0000644000176200001440000000046614476051113017232 0ustar liggesuserscontext("qs import/export") require("datasets") test_that("Export to qs", { skip_if_not_installed(pkg = "qs") expect_true(export(iris, "iris.qs") %in% dir()) }) test_that("Import from qs", { skip_if_not_installed(pkg = "qs") expect_true(is.data.frame(import("iris.qs"))) }) unlink("iris.qs") rio/tests/testthat/test_format_csv_gz.R0000644000176200001440000000041714047423624020102 0ustar liggesuserscontext(".csv.gz imports/exports") require("datasets") test_that("Export to csv.gz", { expect_true(export(iris, "iris.csv.gz") %in% dir()) }) test_that("Import from csv.gz", { expect_true(inherits(import("iris.csv.gz"), "data.frame")) }) unlink("iris.csv.gz") rio/tests/testthat/test_format_fortran.R0000644000176200001440000000041014047423624020253 0ustar liggesuserscontext("Fortran imports/exports") test_that("Import from Fortran", { ff <- tempfile() cat(file = ff, "123456", "987654", sep = "\n") expect_true(inherits(import(ff, format = "fortran", style = c("F2.1","F2.0","I2")), "data.frame")) unlink(ff) }) rio/tests/testthat/test_format_rdata.R0000644000176200001440000000153714500606254017702 0ustar liggesuserscontext("Rdata imports/exports") require("datasets") test_that("Export to Rdata", { # data.frame expect_true(export(iris, "iris.Rdata") %in% dir()) # environment e <- new.env() e$iris <- iris expect_true(export(e, "iris.Rdata") %in% dir()) # character expect_true(export("iris", "iris.Rdata") %in% dir()) # expect error otherwise expect_error(export(iris$Species, "iris.Rdata") %in% dir()) }) test_that("Import from Rdata", { expect_true(is.data.frame(import("iris.Rdata"))) expect_true(is.data.frame(import("iris.Rdata", which = 1))) }) test_that("Export to rda", { expect_true(export(iris, "iris.rda") %in% dir()) }) test_that("Import from rda", { expect_true(is.data.frame(import("iris.rda"))) expect_true(is.data.frame(import("iris.rda", which = 1))) }) unlink("iris.Rdata") unlink("iris.rda") rio/tests/testthat/test_format_R.R0000644000176200001440000000060014047423624017002 0ustar liggesuserscontext("R dump imports/exports") require("datasets") test_that("Export to .R dump file", { expect_true(export(iris, "iris.R") %in% dir()) expect_true(export(iris, "iris.dump") %in% dir()) }) test_that("Import from .R dump file", { expect_true(is.data.frame(import("iris.R"))) expect_true(is.data.frame(import("iris.dump"))) }) unlink("iris.R") unlink("iris.dump") rio/tests/testthat/test_convert.R0000644000176200001440000000163614047423624016723 0ustar liggesuserscontext("Convert") library("datasets") export(mtcars, "mtcars.dta") test_that("Basic file conversion", { convert("mtcars.dta", "mtcars.csv") convert("mtcars.csv", "mtcars.dta") x <- import("mtcars.dta") expect_true(identical(names(mtcars), names(x))) expect_true(identical(dim(mtcars), dim(x))) unlink("mtcars.csv") }) test_that("File conversion with arguments", { export(mtcars, "mtcars.csv", format = "tsv") convert("mtcars.csv", "mtcars.csv", in_opts = list(format = "tsv")) expect_true("mtcars.csv" %in% dir()) expect_true(!("mtcars.tsv" %in% dir())) convert("mtcars.csv", "mtcars.tsv", in_opts = list(format = "tsv"), out_opts = list(format = "csv")) expect_true("mtcars.tsv" %in% dir()) unlink("mtcars.csv") unlink("mtcars.tsv") }) test_that("File conversion w/o out_file errors", { expect_error(convert("mtcars.dta")) }) unlink("mtcars.dta") rio/tests/testthat/test_format_json.R0000644000176200001440000000157014476051106017557 0ustar liggesuserscontext("JSON imports/exports") require("datasets") test_that("Export to JSON", { skip_if_not_installed("jsonlite") expect_true(export(iris, "iris.json") %in% dir()) }) test_that("Import from JSON", { skip_if_not_installed("jsonlite") expect_true(is.data.frame(import("iris.json"))) }) test_that("Export to JSON (non-data frame)", { skip_if_not_installed("jsonlite") expect_true(export(list(1:10, letters), "list.json") %in% dir()) expect_true(inherits(import("list.json"), "list")) expect_true(length(import("list.json")) == 2L) }) test_that("utf-8", { content <- c("\"", "\u010d", "\u0161", "\u00c4", "\u5b57", "\u30a2", "\u30a2\u30e0\u30ed") x <- data.frame(col = content) tempjson <- tempfile(fileext = ".json") y <- import(export(x, tempjson)) testthat::expect_equal(content, y$col) }) unlink("iris.json") unlink("list.json") rio/tests/testthat/test_format_csvy.R0000644000176200001440000000047714047423624017601 0ustar liggesuserscontext("CSVY imports/exports") require("datasets") tmp <- tempfile(fileext = ".csvy") test_that("Export to CSVY", { suppressWarnings(expect_true(file.exists(export(iris, tmp)))) }) test_that("Import from CSVY", { suppressWarnings(d <- import(tmp)) expect_true(inherits(d, "data.frame")) }) unlink(tmp) rio/tests/testthat/test_format_mtp.R0000644000176200001440000000014514047423624017405 0ustar liggesuserscontext("Minitab (.mtp) imports/exports") require("datasets") #test_that("Import from Minitab", {}) rio/tests/testthat/test_format_rec.R0000644000176200001440000000014514047423624017356 0ustar liggesuserscontext("Epiinfo (.rec) imports/exports") require("datasets") #test_that("Import from Epiinfo", {}) rio/tests/testdata/0000755000176200001440000000000014477067105014031 5ustar liggesusersrio/tests/testdata/twotables.html0000644000176200001440000003670214476051106016724 0ustar liggesusers R Exported Data
mpgcyldisphpdratwtqsecvsamgearcarb
2161601103.92.6216.460144
2161601103.92.87517.020144
22.84108933.852.3218.611141
21.462581103.083.21519.441031
18.783601753.153.4417.020032
18.162251052.763.4620.221031
14.383602453.213.5715.840034
24.44146.7623.693.19201042
22.84140.8953.923.1522.91042
19.26167.61233.923.4418.31044
17.86167.61233.923.4418.91044
16.48275.81803.074.0717.40033
17.38275.81803.073.7317.60033
15.28275.81803.073.78180033
10.484722052.935.2517.980034
10.4846021535.42417.820034
14.784402303.235.34517.420034
32.4478.7664.082.219.471141
30.4475.7524.931.61518.521142
33.9471.1654.221.83519.91141
21.54120.1973.72.46520.011031
15.583181502.763.5216.870032
15.283041503.153.43517.30032
13.383502453.733.8415.410034
19.284001753.083.84517.050032
27.3479664.081.93518.91141
264120.3914.432.1416.70152
30.4495.11133.771.51316.91152
15.883512644.223.1714.50154
19.761451753.622.7715.50156
1583013353.543.5714.60158
21.441211094.112.7818.61142

Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
5.13.51.40.2setosa
4.931.40.2setosa
4.73.21.30.2setosa
4.63.11.50.2setosa
53.61.40.2setosa
5.43.91.70.4setosa
4.63.41.40.3setosa
53.41.50.2setosa
4.42.91.40.2setosa
4.93.11.50.1setosa
5.43.71.50.2setosa
4.83.41.60.2setosa
4.831.40.1setosa
4.331.10.1setosa
5.841.20.2setosa
5.74.41.50.4setosa
5.43.91.30.4setosa
5.13.51.40.3setosa
5.73.81.70.3setosa
5.13.81.50.3setosa
5.43.41.70.2setosa
5.13.71.50.4setosa
4.63.610.2setosa
5.13.31.70.5setosa
4.83.41.90.2setosa
531.60.2setosa
53.41.60.4setosa
5.23.51.50.2setosa
5.23.41.40.2setosa
4.73.21.60.2setosa
4.83.11.60.2setosa
5.43.41.50.4setosa
5.24.11.50.1setosa
5.54.21.40.2setosa
4.93.11.50.2setosa
53.21.20.2setosa
5.53.51.30.2setosa
4.93.61.40.1setosa
4.431.30.2setosa
5.13.41.50.2setosa
53.51.30.3setosa
4.52.31.30.3setosa
4.43.21.30.2setosa
53.51.60.6setosa
5.13.81.90.4setosa
4.831.40.3setosa
5.13.81.60.2setosa
4.63.21.40.2setosa
5.33.71.50.2setosa
53.31.40.2setosa
73.24.71.4versicolor
6.43.24.51.5versicolor
6.93.14.91.5versicolor
5.52.341.3versicolor
6.52.84.61.5versicolor
5.72.84.51.3versicolor
6.33.34.71.6versicolor
4.92.43.31versicolor
6.62.94.61.3versicolor
5.22.73.91.4versicolor
523.51versicolor
5.934.21.5versicolor
62.241versicolor
6.12.94.71.4versicolor
5.62.93.61.3versicolor
6.73.14.41.4versicolor
5.634.51.5versicolor
5.82.74.11versicolor
6.22.24.51.5versicolor
5.62.53.91.1versicolor
5.93.24.81.8versicolor
6.12.841.3versicolor
6.32.54.91.5versicolor
6.12.84.71.2versicolor
6.42.94.31.3versicolor
6.634.41.4versicolor
6.82.84.81.4versicolor
6.7351.7versicolor
62.94.51.5versicolor
5.72.63.51versicolor
5.52.43.81.1versicolor
5.52.43.71versicolor
5.82.73.91.2versicolor
62.75.11.6versicolor
5.434.51.5versicolor
63.44.51.6versicolor
6.73.14.71.5versicolor
6.32.34.41.3versicolor
5.634.11.3versicolor
5.52.541.3versicolor
5.52.64.41.2versicolor
6.134.61.4versicolor
5.82.641.2versicolor
52.33.31versicolor
5.62.74.21.3versicolor
5.734.21.2versicolor
5.72.94.21.3versicolor
6.22.94.31.3versicolor
5.12.531.1versicolor
5.72.84.11.3versicolor
6.33.362.5virginica
5.82.75.11.9virginica
7.135.92.1virginica
6.32.95.61.8virginica
6.535.82.2virginica
7.636.62.1virginica
4.92.54.51.7virginica
7.32.96.31.8virginica
6.72.55.81.8virginica
7.23.66.12.5virginica
6.53.25.12virginica
6.42.75.31.9virginica
6.835.52.1virginica
5.72.552virginica
5.82.85.12.4virginica
6.43.25.32.3virginica
6.535.51.8virginica
7.73.86.72.2virginica
7.72.66.92.3virginica
62.251.5virginica
6.93.25.72.3virginica
5.62.84.92virginica
7.72.86.72virginica
6.32.74.91.8virginica
6.73.35.72.1virginica
7.23.261.8virginica
6.22.84.81.8virginica
6.134.91.8virginica
6.42.85.62.1virginica
7.235.81.6virginica
7.42.86.11.9virginica
7.93.86.42virginica
6.42.85.62.2virginica
6.32.85.11.5virginica
6.12.65.61.4virginica
7.736.12.3virginica
6.33.45.62.4virginica
6.43.15.51.8virginica
634.81.8virginica
6.93.15.42.1virginica
6.73.15.62.4virginica
6.93.15.12.3virginica
5.82.75.11.9virginica
6.83.25.92.3virginica
6.73.35.72.5virginica
6.735.22.3virginica
6.32.551.9virginica
6.535.22virginica
6.23.45.42.3virginica
5.935.11.8virginica
rio/tests/testdata/two-tbody.html0000644000176200001440000000024514476051106016641 0ustar liggesusers
DatasetDescription
COComments
rio/tests/testdata/br-in-td.html0000644000176200001440000000024714476051106016327 0ustar liggesusers
RowSTUDYID
1
2
rio/tests/testdata/mtcars.ods0000644000176200001440000001204514476051106016024 0ustar liggesusersPK !l9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPK!o0ToO styles.xmlVn0? z%eAb!J-zd&)Tl;ܴ4N[s͛O=OިL %T0UJ\ Z3Gٶвd06gNu. 9JkK{ bRʁS.K |'.s6:;wq|fȥ]%F[/,zfZYC8"V {怄} 5̃9m;r|Ym %H(+X fi- |wW;@sfZ+ xp#_(1:!#zSs tZ5;Ct m/j_rqPK!e content.xml]Msݧ*^g~&b'ߧ[-]t+0z/>COtiN~ؼXeIj?MzEoqmSߞl\%vȒnJ/6%@߷)fe#5JjCcWmN+[<,<. բ|eMOk=; n>'?|W" 3ܾ֮^-W82ʩ;]4N(_?א ëT\c|>%q6IH0V}R0Ym`OCП< Ǐ< O"Bef4¿`w.z\9t\|:̓M N7n+,QY&tmƘEڏf7Zg96yn7x3Ǣ1Y&Z͆ :a0ZE0o4;UCbHv/r冰Q.<ٸHom8LY}H: x2Q~`:^ VL=f/.˼> ;ӥ_}x([xa H32u&d-D.@Qhq(ٟ@DŽh($W\4CИ·A)2FW0pF_N<~S[qu.+ MЏM*UM0|JT= 3^u&ؙɆ2Lr`ir!ƪ G]ENPNp:,,a0j\%7QPO8>mdل3 KĘ-q|(/ vc6\S #EE'Yȴ ԁrj _(T(PĽ02s/qPaƪ11 C9@,dќ^CU(P&b<5ge/kd]fr:"!0nlF]j Fr}ADkOBY o}i;_lŇO/}AM0tɪb|*o:jBټQ#.d4Mӊ`lBafPwQ1.9 re`6C٩tE>EmFD^+|zb9%f)>eBa:N v㲝4.v8ɄW*jD\AI>z+d+٠3h]6M'0V}TˏƠ-O7T#٠tEM0G_) 3׿(L: #9vPLe *,襄 hFvka#OsXT7eB[=p4**"#31 "FqD@\̩5\茼w&ݛ3u&NϏ˳Ħ6A70/ ]u0RD#PhVZa"M.03,-[;֝b-Bv*aZNr=&͋0?${|b ^68ɋ;>3 rSKY\Afav+^aspӑC NQ i^&N w_Z:t_iaZ l20@Ҳor`nO-NGM@|3μ_ވ܅^7@/nm\S |Iu_tLvU{]=Im~B;nmnEjm<[}o%ݔ^mJ?PK!META-INF/manifest.xmlAj1 Ex?v+&z4[6#M>NavQH;I}y8N8sμhjL P\ ^a|~4! Iķe&W;$ڐb KAs];C_Wܴ<4VcAAk9~=Q4_w6#D>"Y֌lz_Ԃg?@C%G3H{ܭ/PK!Evmeta.xmlR;o0+? `L jUC6˾V٦` "Qw>؞k}u$Ehn gZ0e4Vw9$* oj>3ӎPaN:Y zN $s6 No_uϝk/ѧ'*1Ǡa=J mۤ]E㝳2TMӫ"p ycWɭqBD44~`7.!,YZ\j%S1F_F-RNXz h77CdlvdA9]57Chw -TMoI PK- !l9..mimetypePK-!o0ToO Tstyles.xmlPK-!e content.xmlPK-!yMETA-INF/manifest.xmlPK-!Evmeta.xmlPK rio/tests/testdata/br-in-header.html0000644000176200001440000000023214476051106017142 0ustar liggesusers

Date
1December 15, 2003 13:14:17.123
rio/tests/testdata/th-as-row-element.html0000644000176200001440000000024414476051106020160 0ustar liggesusers
RowSTUDYID
1ABC
2ABC
rio/tests/testdata/example.csvy0000644000176200001440000000045414476051106016366 0ustar liggesusers--- name: my-dataset fields: - name: var1 title: variable 1 type: string description: explaining var1 constraints: - required: true - name: var2 title: variable 2 type: integer - name: var3 title: variable 3 type: number --- var1,var2,var3 A,1,2.5 B,3,4.3 rio/tests/testdata/iris.xls0000644000176200001440000005200014476051106015515 0ustar liggesusersࡱ; '%  !"#$(Root Entry  \pCalc Ba==@ 8@"1Calibri1Arial1Arial1Arial General                + ) , *    `DSheet1;4Sheet2TbZ 3  @@   Sepal.Length Sepal.Width Petal.Length Petal.WidthSpeciessetosa versicolor virginicampgcyldisphpdratwtqsecvsamgearcarbcc   dMbP?_%*+$!&C&"Times New Roman,Regular"&12&A)&&C&"Times New Roman,Regular"&12Page &P&333333?'333333?(-؂-?)-؂-?"d,,333333?333333?U           ffffff@{3S @3S [ S ffffff@[S 3S s433333?~  ffffff@S3433333? S[S  @ 3S  @ [+  s[S  SS  3+ ?~ +  S ~ @[ s  ffffff@{3433333? 433333?433333? ffffff@[433333? sS433333?~ S ffffff@[ ffffff@S ffffff@~ +433333?~  SS S S #{[S #S3S [S S  !"#$%&'()*+,-./0123456789:;<=>? sS[ ~ !#!ffffff@![+ !"3S "#@#[S #$S $%{ S %&@&3+ &'@' S '(ffffff@(S[S (){ )433333? )~ * *ffffff@~ * *433333? *+@+ S +,{,433333? ,-ffffff@- -.3.433333? ./ffffff@/S /0ffffff@03S 01K[S 12+3S 23[3 34  [ 45 5@~ 5[ 5~ 66ffffff@6  67+ c7ffffff@~ 7[ 78c   89 +[ 9:@:+ :;S ;ffffff@~ ;  ;<#;3 <= { =>; [ >~ ??@? ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_@ [3 @A  AB{ B@~ B3 BC [ CD ;Dffffff@~ D D~ E E@E [ EFF? FG;  GH c  HI I@~ I[ IJ c[ JK   KLS L@~ L3 LM c3 MN{ N433333? NO [ OP{ PQQ? QR RS ; ST;Tffffff@~ T TUs [ UVS  VW{ [[ W~ X Xffffff@X@~ X  XYYffffff@~ Y  YZ  Z[[@~ [ [\ \ffffff@~ \3 \]  ]~ ^^ffffff@^+ ^_;  _`abcdefghijklmnopqrstuvwxyz{|}~` `a  ab   bcffffff@cc? cdcdffffff@~ d  de + ef ;fffffff@~ f fg ; K gh  hi+  i@ ij S K jk@k k433333? klk   lm{   mnC   no+ offffff@~ o op ;K pq K qr  rs csffffff@~ s st Ktffffff@ tu+  uv { v@ vw  wffffff@ w~ xx@x[ xy yffffff@ yzcz@~ z z{ c{   {| ;|@~ | |}{ +K }~C  ~ c  @~   cK C    c  [     c@  cffffff@~ [  3   ffffff@  S     sK {   ffffff@ffffff@  ;ffffff@~   ; ffffff@ { + { #ffffff@   + #   Ssffffff@ ; ffffff@~  PH0(  >@gg   dMbP?_%,*+&ffffff?'ffffff?(333333?)333333?"d,,333333?333333?U} !  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,           HV $V@$ $#v(\@$ $s! Q @q= ףp3@ H;"c 2@BSk H[" #&fffffVb@6R  # a@6 ~## H #c * #c fffff2@   ffffff0@$ "_ ffffff1@  *  " 1@  H"J HC"b67 $C"2^V-@$ $"zGa@Qk1@ $2z c@$o $/Kvףp= ?$ 4fffffQ@\(\?fffff3@ $!Q@(\4@ H;"ZS_ $"Z{Gz @$  H"z $"B(\@$ $*> c(\?fffff2@ Hjn[ $/h|?5?fffff0@ H"~" HFW; H>">"  , s! q= ףp@~ [ 2@  PH 0(  >@gg  FMicrosoft Excel 97-TabelleBiff8Oh+'0@H T ` l x TJL1@;9@@r@"m՜.+,D՜.+,\Root EntryF&WorkbookDCompObjIOle SummaryInformation(DocumentSummaryInformation8trio/tests/testdata/noheader.csv0000644000176200001440000000070714476051106016330 0ustar liggesusers0,??,?,Total,1998,46991171,23594034,23397137 0,??,0 - 4?,0 ,1998,3390678,1788561,1602117 0,??,5 - 9?,5 ,1998,3428387,1820224,1608163 0,??,10 - 14?,10,1998,3195174,1668531,1526643 0,??,15 - 19?,15,1998,4094035,2102515,1991520 0,??,20 - 24?,20,1998,3942827,2022535,1920292 0,??,25 - 29?,25,1998,4637577,2371635,2265942 0,??,30 - 34?,30,1998,4375695,2239107,2136588 0,??,35 - 39?,35,1998,4502137,2308132,2194005 0,??,40 - 44?,40,1998,3754895,1924704,1830191 rio/tests/testthat.R0000644000176200001440000000011314476051106014167 0ustar liggesuserslibrary("testthat") library("rio") test_check("rio", reporter = "summary") rio/vignettes/0000755000176200001440000000000014502270453013055 5ustar liggesusersrio/vignettes/extension.Rmd0000644000176200001440000000473014500415343015536 0ustar liggesusers--- title: "Extending rio" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Extending rio} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(rio) ``` rio implements format-specific S3 methods for each type of file that can be imported from or exported to. This happens via internal S3 generics, `.import` and `.export`. It is possible to write new methods like with any S3 generic (e.g., `print`). As an example, `.import.rio_csv` imports from a comma-separated values file. If you want to produce a method for a new filetype with extension `myfile`, you simply have to create a function called `.import.rio_myfile` that implements a format-specific importing routine and returns a data.frame. rio will automatically recognize new S3 methods, so that you can then import your file using: `import("file.myfile")`. The way to develop `export` method is same: `.export.rio_csv`. The first two parameters of `.export` are `file` (file name) and `x` (data frame to be exported). As general guidance, if an import method creates many attributes, these attributes should be stored --- to the extent possible --- in variable-level attributes fields. These can be gathered to the data.frame level by the user via `gather_attrs`. # Examples ## arff The following example shows how the arff import and export methods are implemented internally. ```r .import.rio_arff <- function(file, which = 1, ...) { foreign::read.arff(file = file) } .export.rio_arff <- function(file, x, ...) { foreign::write.arff(x = x, file = file, ...) } ``` ## ledger This is the example from the `ledger` package (MIT) by Dr Trevor L David . ```r .import.rio_ledger <- register # nolint register <- function(file, ..., toolchain = default_toolchain(file), date = NULL) { .assert_toolchain(toolchain) switch(toolchain, "ledger" = register_ledger(file, ..., date = date), "hledger" = register_hledger(file, ..., date = date), "beancount" = register_beancount(file, ..., date = date), "bean-report_ledger" = { file <- .bean_report(file, "ledger") on.exit(unlink(file)) register_ledger(file, ..., date = date) }, "bean-report_hledger" = { file <- .bean_report(file, "hledger") on.exit(unlink(file)) register_hledger(file, ..., date = date) } ) } ``` rio/vignettes/labelled.Rmd0000644000176200001440000000247614500527537015304 0ustar liggesusers--- title: "Working with labelled data" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Working with labelled data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r} library(rio) library(haven) ``` Formats SAS, SPSS, and Stata use `haven` as import and export functions. And these formats can have the so-called labelled data. For more information, please read `vignette("semantics", "haven")`. Here, we provide a quick guide on how to work with labelled data using `rio`. You can use `haven::labelled()` to create labelled data. ```{r} gender <- haven::labelled( c("M", "F", "F", "F", "M"), c(Male = "M", Female = "F")) ``` Or directly using `attrs` ```{r} rating <- sample(1:5) attr(rating, "labels") <- c(c(Good = 1, Bad = 5)) ``` ```{r} mydata <- data.frame(gender, rating) ``` Round trip: The data labels are retained. But they are at the variable level. ```{r} export(mydata, "mydata.sav") restored_data <- rio::import("mydata.sav") str(restored_data) ``` `rio::gather_attrs()` converts attributes to the data.frame level ```{r} g <- rio::gather_attrs(restored_data) str(g) attr(g, "labels") ``` ```{r include = FALSE} unlink("mydata.sav") ``` rio/vignettes/remap.Rmd0000644000176200001440000000426714500415343014633 0ustar liggesusers--- title: "Remapping and Ellipsis" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Remapping and Ellipsis} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` # Remapping There are two conventions of arguments among the underlying functions used by `rio`. Let's call them *Base Convention* and *"Tidy" Convention*. | Convention | file location | selection of sheet | header | examples | |------------|---------------|--------------------|-------------|--------------------------------------------------------------| | Base | `file` | `which` | `header` | `clipr::read_clip_tbl` | | "Tidy" | `path` | `sheet` | `col_names` | `readxl::read_xlsx`, `readxl::read_xls`, `readODS::read_ods` | `rio` can map Base Convention into "Tidy" Convention (but not vice versa). ```{r map1} library(rio) export(list("mtcars" = mtcars, "iris" = iris), "example.xlsx") import("example.xlsx", which = "mtcars") ``` But you can still use the "Tidy" Convention, if the underlying function supports it. ```{r map2} import("example.xlsx", sheet = "mtcars") ``` # Ellipsis or "dot dot dot" Additional parameters are usually passed to the underlying function as ellipsis (`...`). ```{r map3} ## n_max is an argument of readxl::read_xlsx import("example.xlsx", sheet = "iris", n_max = 10) ``` Parameters that the underlying function do not recognize are silently ignored by default. ```{r map4} import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") ``` If you don't like this behavior, please change the option `rio.ignoreunusedargs` to `FALSE`, i.e. `option(rio.ignoreunusedargs = FALSE)`. ```r options(rio.ignoreunusedargs = FALSE) import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") ``` ```{r map5, error = TRUE, echo = FALSE} R.utils::withOptions({ import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") }, rio.ignoreunusedargs = FALSE) ``` ```{r, echo = FALSE, results = 'hide'} unlink("example.xlsx") ``` rio/vignettes/rio.Rmd0000644000176200001440000002376514476565060014342 0ustar liggesusers--- title: "Import, Export, and Convert Data Files" date: "`r Sys.Date()`" output: html_document: fig_caption: false toc: true toc_float: collapsed: false smooth_scroll: false toc_depth: 3 vignette: > %\VignetteIndexEntry{Introduction to 'rio'} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # Import, Export, and Convert Data Files The idea behind **rio** is to simplify the process of importing data into R and exporting data from R. This process is, probably unnecessarily, extremely complex for beginning R users. Indeed, R supplies [an entire manual](https://cran.r-project.org/doc/manuals/r-release/R-data.html) describing the process of data import/export. And, despite all of that text, most of the packages described are (to varying degrees) out-of-date. Faster, simpler, packages with fewer dependencies have been created for many of the file types described in that document. **rio** aims to unify data I/O (importing and exporting) into two simple functions: `import()` and `export()` so that beginners (and experienced R users) never have to think twice (or even once) about the best way to read and write R data. The core advantage of **rio** is that it makes assumptions that the user is probably willing to make. Specifically, **rio** uses the file extension of a file name to determine what kind of file it is. This is the same logic used by Windows OS, for example, in determining what application is associated with a given file type. By taking away the need to manually match a file type (which a beginner may not recognize) to a particular import or export function, **rio** allows almost all common data formats to be read with the same function. By making import and export easy, it's an obvious next step to also use R as a simple data conversion utility. Transferring data files between various proprietary formats is always a pain and often expensive. The `convert` function therefore combines `import` and `export` to easily convert between file formats (thus providing a FOSS replacement for programs like [Stat/Transfer](https://stattransfer.com/) or [Sledgehammer](https://www.mtna.us/#/products/sledgehammer)). ## Supported file formats **rio** supports a variety of different file formats for import and export. To keep the package slim, all non-essential formats are supported via "Suggests" packages, which are not installed (or loaded) by default. To ensure rio is fully functional, install these packages the first time you use **rio** via: ```R install_formats() ``` The full list of supported formats is below: ```{r, include = FALSE} suppressPackageStartupMessages(library(data.table)) ``` ```{r featuretable, echo = FALSE} rf <- data.table(rio:::rio_formats)[!input %in% c(",", ";", "|", "\\t") & type %in% c("import", "suggest", "archive"),] short_rf <- rf[, paste(input, collapse = " / "), by = format_name] type_rf <- unique(rf[,c("format_name", "type", "import_function", "export_function", "note")]) feature_table <- short_rf[type_rf, on = .(format_name)] colnames(feature_table)[2] <- "signature" setorder(feature_table, "type", "format_name") feature_table$import_function <- stringi::stri_extract_first(feature_table$import_function, regex = "[a-zA-Z0-9\\.]+") feature_table$import_function[is.na(feature_table$import_function)] <- "" feature_table$export_function <- stringi::stri_extract_first(feature_table$export_function, regex = "[a-zA-Z0-9\\.]+") feature_table$export_function[is.na(feature_table$export_function)] <- "" feature_table$type <- ifelse(feature_table$type %in% c("suggest"), "Suggest", "Default") feature_table <- feature_table[,c("format_name", "signature", "import_function", "export_function", "type", "note")] colnames(feature_table) <- c("Name", "Extensions / \"format\"", "Import Package", "Export Package", "Type", "Note") knitr::kable(feature_table) ``` Additionally, any format that is not supported by **rio** but that has a known R implementation will produce an informative error message pointing to a package and import or export function. Unrecognized formats will yield a simple "Unrecognized file format" error. ## Data Import **rio** allows you to import files in almost any format using one, typically single-argument, function. `import()` infers the file format from the file's extension and calls the appropriate data import function for you, returning a simple data.frame. This works for any for the formats listed above. ```{r, echo=FALSE, results='hide'} library("rio") export(mtcars, "mtcars.csv") export(mtcars, "mtcars.rds") export(mtcars, "mtcars.dta") export(mtcars, "mtcars_noext", format = "csv") ``` ```{r} library("rio") x <- import("mtcars.csv") y <- import("mtcars.rds") z <- import("mtcars.dta") # confirm identical all.equal(x, y, check.attributes = FALSE) all.equal(x, z, check.attributes = FALSE) ``` If for some reason a file does not have an extension, or has a file extension that does not match its actual type, you can manually specify a file format to override the format inference step. For example, we can read in a CSV file that does not have a file extension by specifying `csv`: ```{r} head(import("mtcars_noext", format = "csv")) ``` ```{r, echo=FALSE, results='hide'} unlink("mtcars.csv") unlink("mtcars.rds") unlink("mtcars.dta") unlink("mtcars_noext") ``` ### Importing Data Lists Sometimes you may have multiple data files that you want to import. `import()` only ever returns a single data frame, but `import_list()` can be used to import a vector of file names into R. This works even if the files are different formats: ```r str(import_list(dir()), 1) ``` Similarly, some single-file formats (e.g. Excel Workbooks, Zip directories, HTML files, etc.) can contain multiple data sets. Because `import()` is type safe, always returning a data frame, importing from these formats requires specifying a `which` argument to `import()` to dictate which data set (worksheet, file, table, etc.) to import (the default being `which = 1`). But `import_list()` can be used to import all (or only a specified subset, again via `which`) of data objects from these types of files. ## Data Export The export capabilities of **rio** are somewhat more limited than the import capabilities, given the availability of different functions in various R packages and because import functions are often written to make use of data from other applications and it never seems to be a development priority to have functions to export to the formats used by other applications. That said, **rio** currently supports the following formats: ```{r} library("rio") export(mtcars, "mtcars.csv") export(mtcars, "mtcars.rds") export(mtcars, "mtcars.dta") ``` It is also easy to use `export()` as part of an R pipeline (from magrittr or dplyr). For example, the following code uses `export()` to save the results of a simple data transformation: ```{r} library("magrittr") mtcars %>% subset(hp > 100) %>% aggregate(. ~ cyl + am, data = ., FUN = mean) %>% export(file = "mtcars2.dta") ``` Some file formats (e.g., Excel workbooks, Rdata files) can support multiple data objects in a single file. `export()` natively supports output of multiple objects to these types of files: ```{r} # export to sheets of an Excel workbook export(list(mtcars = mtcars, iris = iris), "multi.xlsx") ``` ```{r} # export to an .Rdata file ## as a named list export(list(mtcars = mtcars, iris = iris), "multi.rdata") ## as a character vector export(c("mtcars", "iris"), "multi.rdata") ``` It is also possible to use the new (as of v0.6.0) function `export_list()` to write a list of data frames to multiple files using either a vector of file names or a file pattern: ```{r} export_list(list(mtcars = mtcars, iris = iris), "%s.tsv") ``` ## File Conversion The `convert()` function links `import()` and `export()` by constructing a dataframe from the imported file and immediately writing it back to disk. `convert()` invisibly returns the file name of the exported file, so that it can be used to programmatically access the new file. Because `convert()` is just a thin wrapper for `import()` and `export()`, it is very easy to use. For example, we can convert ```{r} # create file to convert export(mtcars, "mtcars.dta") # convert Stata to SPSS convert("mtcars.dta", "mtcars.sav") ``` `convert()` also accepts lists of arguments for controlling import (`in_opts`) and export (`out_opts`). This can be useful for passing additional arguments to import or export methods. This could be useful, for example, for reading in a fixed-width format file and converting it to a comma-separated values file: ```{r} # create an ambiguous file fwf <- tempfile(fileext = ".fwf") cat(file = fwf, "123456", "987654", sep = "\n") # see two ways to read in the file identical(import(fwf, widths = c(1, 2, 3)), import(fwf, widths = c(1, -2, 3))) # convert to CSV convert(fwf, "fwf.csv", in_opts = list(widths = c(1, 2, 3))) import("fwf.csv") # check conversion ``` ```{r, echo=FALSE, results='hide'} unlink("mtcars.dta") unlink("mtcars.sav") unlink("fwf.csv") unlink(fwf) ``` With metadata-rich file formats (e.g., Stata, SPSS, SAS), it can also be useful to pass imported data through `characterize()` or `factorize()` when converting to an open, text-delimited format: `characterize()` converts a single variable or all variables in a data frame that have "labels" attributes into character vectors based on the mapping of values to value labels (e.g., `export(characterize(import("file.dta")), "file.csv")`). An alternative approach is exporting to CSVY format, which records metadata in a YAML-formatted header at the beginning of a CSV file. It is also possible to use **rio** on the command-line by calling `Rscript` with the `-e` (expression) argument. For example, to convert a file from Stata (.dta) to comma-separated values (.csv), simply do the following: ``` Rscript -e "rio::convert('mtcars.dta', 'mtcars.csv')" ``` ```{r, echo=FALSE, results='hide'} unlink("mtcars.csv") unlink("mtcars.rds") unlink("mtcars.rdata") unlink("mtcars.dta") unlink("multi.xlsx") unlink("multi.rdata") unlink("mtcars2.dta") unlink("mtcars.tsv") unlink("iris.tsv") ``` rio/vignettes/philosophy.Rmd0000644000176200001440000001012114476074062015722 0ustar liggesusers--- title: "Package Philosophy" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Package Philosophy} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The core advantage of **rio** is that it makes assumptions that the user is probably willing to make. Eight of these are important: 1. **rio** uses the file extension of a file name to determine what kind of file it is. This is the same logic used by Windows OS, for example, in determining what application is associated with a given file type. By removing the need to manually match a file type (which a beginner may not recognize) to a particular import or export function, **rio** allows almost all common data formats to be read with the same function. And if a file extension is incorrect, users can force a particular import method by specifying the `format` argument. 2. **rio** uses `data.table::fread()` for text-delimited files to automatically determine the file format regardless of the extension. So, a CSV that is actually tab-separated will still be correctly imported. It's also crazy fast. 3. **rio**, wherever possible, does not import character strings as factors. 4. **rio** supports web-based imports natively, including from SSL (HTTPS) URLs, from shortened URLs, from URLs that lack proper extensions, and from (public) Google Documents Spreadsheets. 5. **rio** imports from from single-file .zip and .tar archives automatically, without the need to explicitly decompress them. Export to compressed directories is also supported. 6. **rio** wraps a variety of faster, more stream-lined I/O packages than those provided by base R or the **foreign** package. It uses [**data.table**](https://cran.r-project.org/package=data.table) for delimited formats, [**haven**](https://cran.r-project.org/package=haven) for SAS, Stata, and SPSS files, smarter and faster fixed-width file import and export routines, and [**readxl**](https://cran.r-project.org/package=readxl) and [**openxlsx**](https://cran.r-project.org/package=openxlsx) for reading and writing Excel workbooks. 7. **rio** stores metadata from rich file formats (SPSS, Stata, etc.) in variable-level attributes in a consistent form regardless of file type or underlying import function. These attributes are identified as: - `label`: a description of variable - `labels`: a vector mapping numeric values to character strings those values represent - `format`: a character string describing the variable storage type in the original file The `gather_attrs()` function makes it easy to move variable-level attributes to the data frame level (and `spread_attrs()` reverses that gathering process). These can be useful, especially, during file conversion to more easily modify attributes that are handled differently across file formats. As an example, the following idiom can be used to trim SPSS value labels to the 32-character maximum allowed by Stata: ```R dat <- gather_attrs(rio::import("data.sav")) attr(dat, "labels") <- lapply(attributes(dat)$labels, function(x) { if (!is.null(x)) { names(x) <- substring(names(x), 1, 32) } x }) export(spread_attrs(dat), "data.dta") ``` In addition, two functions (added in v0.5.5) provide easy ways to create character and factor variables from these "labels" attributes. `characterize()` converts a single variable or all variables in a data frame that have "labels" attributes into character vectors based on the mapping of values to value labels. `factorize()` does the same but returns factor variables. This can be especially helpful for converting these rich file formats into open formats (e.g., `export(characterize(import("file.dta")), "file.csv")`. 8. **rio** imports and exports files based on an internal S3 class infrastructure. This means that other packages can contain extensions to **rio** by registering S3 methods. These methods should take the form `.import.rio_X()` and `.export.rio_X()`, where `X` is the file extension of a file type. An example is provided in the [rio.db package](https://github.com/leeper/rio.db). rio/R/0000755000176200001440000000000014502270161011242 5ustar liggesusersrio/R/import_list.R0000644000176200001440000001434614500577341013752 0ustar liggesusers#' @title Import list of data frames #' @description Use [import()] to import a list of data frames from a vector of file names or from a multi-object file (Excel workbook, .Rdata file, zipped directory in a zip file, or HTML file) #' @param file A character string containing a single file name for a multi-object file (e.g., Excel workbook, zip file, or HTML file), or a vector of file paths for multiple files to be imported. #' @param which If `file` is a single file path, this specifies which objects should be extracted (passed to [import()]'s `which` argument). Ignored otherwise. #' @param rbind A logical indicating whether to pass the import list of data frames through [data.table::rbindlist()]. #' @param rbind_label If `rbind = TRUE`, a character string specifying the name of a column to add to the data frame indicating its source file. #' @param rbind_fill If `rbind = TRUE`, a logical indicating whether to set the `fill = TRUE` (and fill missing columns with `NA`). #' @param \dots Additional arguments passed to [import()]. Behavior may be unexpected if files are of different formats. #' @inheritParams import #' @return If `rbind=FALSE` (the default), a list of a data frames. Otherwise, that list is passed to [data.table::rbindlist()] with `fill = TRUE` and returns a data frame object of class set by the `setclass` argument; if this operation fails, the list is returned. #' @examples #' ## For demo, a temp. file path is created with the file extension .xlsx #' xlsx_file <- tempfile(fileext = ".xlsx") #' export( #' list( #' mtcars1 = mtcars[1:10, ], #' mtcars2 = mtcars[11:20, ], #' mtcars3 = mtcars[21:32, ] #' ), #' xlsx_file #' ) #' #' # import a single file from multi-object workbook #' import(xlsx_file, sheet = "mtcars1") #' # import all worksheets, the return value is a list #' import_list(xlsx_file) #' #' # import and rbind all worksheets, the return valye is a data frame #' import_list(xlsx_file, rbind = TRUE) #' @seealso [import()], [export_list()], [export()] #' @export import_list <- function(file, setclass = getOption("rio.import.class", "data.frame"), which, rbind = FALSE, rbind_label = "_file", rbind_fill = TRUE, ...) { .check_file(file, single_only = FALSE) ## special cases if (length(file) == 1) { x <- .read_file_as_list(file = file, which = which, setclass = setclass, rbind = rbind, rbind_label = rbind_label, ...) } else { ## note the plural x <- .read_multiple_files_as_list(files = file, setclass = setclass, rbind = rbind, rbind_label = rbind_label, ...) } # optionally rbind if (isTRUE(rbind)) { if (length(x) == 1) { x <- x[[1L]] } else { x2 <- try(data.table::rbindlist(x, fill = rbind_fill), silent = TRUE) if (inherits(x2, "try-error")) { warning("Attempt to rbindlist() the data did not succeed. List returned instead.") return(x) } else { x <- x2 } } ## set class x <- set_class(x, class = setclass) } return(x) } .strip_exts <- function(file) { vapply(file, function(x) tools::file_path_sans_ext(basename(x)), character(1)) } .read_multiple_files_as_list <- function(files, setclass, rbind, rbind_label, ...) { names(files) <- .strip_exts(files) x <- lapply(files, function(thisfile) { out <- try(import(thisfile, setclass = setclass, ...), silent = TRUE) if (inherits(out, "try-error")) { warning(sprintf("Import failed for %s", thisfile)) out <- NULL } else if (isTRUE(rbind)) { out[[rbind_label]] <- thisfile } structure(out, filename = thisfile) }) names(x) <- names(files) return(x) } .read_file_as_list <- function(file, which, setclass, rbind, rbind_label, ...) { if (R.utils::isUrl(file)) { file <- remote_to_local(file) } if (get_info(file)$format == "rdata") { e <- new.env() load(file, envir = e) return(as.list(e)) } if (!get_info(file)$format %in% c("html", "xlsx", "xls", "zip")) { which <- 1 whichnames <- NULL } ## getting list of `whichnames` if (get_info(file)$format == "html") { .check_pkg_availability("xml2") tables <- xml2::xml_find_all(xml2::read_html(unclass(file)), ".//table") if (missing(which)) { which <- seq_along(tables) } whichnames <- vapply(xml2::xml_attrs(tables[which]), function(x) if ("class" %in% names(x)) x["class"] else "", FUN.VALUE = character(1) ) names(which) <- whichnames } if (get_info(file)$format %in% c("xls", "xlsx")) { ## .check_pkg_availability("readxl") whichnames <- readxl::excel_sheets(path = file) if (missing(which)) { which <- seq_along(whichnames) names(which) <- whichnames } else if (is.character(which)) { whichnames <- which } else { whichnames <- whichnames[which] } } if (get_info(file)$format %in% c("zip")) { if (missing(which)) { whichnames <- utils::unzip(file, list = TRUE)[, "Name"] which <- seq_along(whichnames) names(which) <- .strip_exts(whichnames) } else if (is.character(which)) { whichnames <- utils::unzip(file, list = TRUE)[, "Name"] whichnames <- whichnames[whichnames %in% which] } else { whichnames <- utils::unzip(file, list = TRUE)[, "Name"] names(which) <- .strip_exts(whichnames) } } ## reading all `whichnames` x <- lapply(which, function(thiswhich) { out <- try(import(file, setclass = setclass, which = thiswhich, ...), silent = TRUE) if (inherits(out, "try-error")) { warning(sprintf("Import failed for %s from %s", thiswhich, file)) out <- NULL } else if (isTRUE(rbind) && length(which) > 1) { out[[rbind_label]] <- thiswhich } out }) names(x) <- whichnames return(x) } rio/R/export_methods.R0000644000176200001440000002350414500667364014452 0ustar liggesusersexport_delim <- function(file, x, fwrite = lifecycle::deprecated(), sep = "\t", row.names = FALSE, col.names = TRUE, append = FALSE, ...) { if (lifecycle::is_present(fwrite)) { lifecycle::deprecate_warn(when = "0.5.31", what = "export(fwrite)", details = "plain text files will always be written with `data.table::fwrite`. The parameter `fwrite` will be dropped in v2.0.0.") } .docall(data.table::fwrite, ..., args = list(x = x, file = file, sep = sep, row.names = row.names, col.names = ifelse(append, FALSE, col.names), append = append)) } #' @export .export.rio_txt <- function(file, x, ...) { export_delim(x = x, file = file, ...) } #' @export .export.rio_tsv <- function(file, x, ...) { export_delim(x = x, file = file, ...) } #' @export .export.rio_csv <- function(file, x, sep = ",", dec = ".", ...) { export_delim(x = x, file = file, sep = sep, dec = dec, ...) } #' @export .export.rio_csv2 <- function(file, x, sep = ";", dec = ",", ...) { export_delim(x = x, file = file, sep = sep, dec = dec, ...) } #' @export .export.rio_csvy <- function(file, x, sep = ",", dec = ".", yaml = TRUE, ...) { export_delim(x = x, file = file, sep = sep, dec = dec, yaml = TRUE, ...) } #' @export .export.rio_psv <- function(file, x, ...) { export_delim(x = x, file = file, sep = "|", ...) } #' @export .export.rio_fwf <- function(file, x, verbose = getOption("verbose", FALSE), sep = "", row.names = FALSE, quote = FALSE, col.names = FALSE, digits = getOption("digits", 7), ...) { dat <- lapply(x, function(col) { if (is.character(col)) { col <- as.numeric(as.factor(col)) } else if (is.factor(col)) { col <- as.integer(col) } if (is.integer(col)) { return(sprintf("%i", col)) } if (is.numeric(col)) { decimals <- strsplit(as.character(col), ".", fixed = TRUE) m1 <- max(nchar(unlist(lapply(decimals, `[`, 1))), na.rm = TRUE) decimals_2 <- unlist(lapply(decimals, `[`, 2)) decimals_2_nchar <- nchar(decimals_2[!is.na(decimals_2)]) if (length(decimals_2_nchar)) { m2 <- max(decimals_2_nchar, na.rm = TRUE) } else { m2 <- 0 } if (!is.finite(m2)) { m2 <- digits } return(formatC(sprintf(fmt = paste0("%0.", m2, "f"), col), width = (m1 + m2 + 1))) } else if (is.logical(col)) { return(sprintf("%i", col)) } }) dat <- do.call(cbind, dat) n <- nchar(dat[1, ]) + c(rep(nchar(sep), ncol(dat) - 1), 0) col_classes <- vapply(x, class, character(1)) col_classes[col_classes == "factor"] <- "integer" dict <- cbind.data.frame( variable = names(n), class = col_classes, width = unname(n), columns = paste0(c(1, cumsum(n) + 1)[-length(n)], "-", cumsum(n)), stringsAsFactors = FALSE ) if (isTRUE(verbose)) { message("Columns:") message(paste0(utils::capture.output(dict), collapse = "\n")) if (sep == "") { message(paste0( "\nRead in with:\n", 'import("', file, '",\n', " widths = c(", paste0(n, collapse = ","), "),\n", ' col.names = c("', paste0(names(n), collapse = '","'), '"),\n', ' colClasses = c("', paste0(col_classes, collapse = '","'), '"))\n' ), domain = NA) } } .write_as_utf8(paste0("#", utils::capture.output(utils::write.csv(dict, row.names = FALSE, quote = FALSE))), file = file, sep = "\n") .docall(utils::write.table, ..., args = list(x = dat, file = file, append = TRUE, row.names = row.names, sep = sep, quote = quote, col.names = col.names)) } #' @export .export.rio_r <- function(file, x, ...) { .docall(dput, ..., args = list(x = x, file = file)) } #' @export .export.rio_dump <- function(file, x, ...) { dump(as.character(substitute(x)), file = file) } #' @export .export.rio_rds <- function(file, x, ...) { .docall(saveRDS, ..., args = list(object = x, file = file)) } #' @export .export.rio_rdata <- function(file, x, ...) { if (isFALSE(is.data.frame(x)) && isFALSE(is.list(x)) && isFALSE(is.environment(x)) && isFALSE(is.character(x))) { stop("'x' must be a data.frame, list, or environment") } if (is.data.frame(x)) { return(save(x, file = file, ...)) } if (is.list(x)) { e <- as.environment(x) return(save(list = names(x), file = file, envir = e, ...)) } if (is.environment(x)) { return(save(list = ls(x), file = file, envir = x, ...)) } return(save(list = x, file = file, ...)) ## characters, but is this doing what it does? } #' @export .export.rio_rda <- .export.rio_rdata #' @export .export.rio_feather <- function(file, x, ...) { .docall(arrow::write_feather, ..., args = list(x = x, sink = file)) } #' @export .export.rio_fst <- function(file, x, ...) { .check_pkg_availability("fst") .docall(fst::write.fst, ..., args = list(x = x, path = file)) } #' @export .export.rio_matlab <- function(file, x, ...) { .check_pkg_availability("rmatio") .docall(rmatio::write.mat, ..., args = list(object = x, filename = file)) } #' @export .export.rio_sav <- function(file, x, ...) { x <- restore_labelled(x) .docall(haven::write_sav, ..., args = list(data = x, path = file)) } #' @export .export.rio_zsav <- function(file, x, compress = TRUE, ...) { x <- restore_labelled(x) .docall(haven::write_sav, ..., args = list(data = x, path = file, compress = compress)) } #' @export .export.rio_dta <- function(file, x, ...) { x <- restore_labelled(x) .docall(haven::write_dta, ..., args = list(data = x, path = file)) } #' @export .export.rio_sas7bdat <- function(file, x, ...) { x <- restore_labelled(x) .docall(haven::write_sas, ..., args = list(data = x, path = file)) } #' @export .export.rio_xpt <- function(file, x, ...) { x <- restore_labelled(x) .docall(haven::write_xpt, ..., args = list(data = x, path = file)) } #' @export .export.rio_dbf <- function(file, x, ...) { .docall(foreign::write.dbf, ..., args = list(dataframe = x, file = file)) } #' @export .export.rio_json <- function(file, x, ...) { .check_pkg_availability("jsonlite") .write_as_utf8(.docall(jsonlite::toJSON, ..., args = list(x = x)), file = file) } #' @export .export.rio_arff <- function(file, x, ...) { .docall(foreign::write.arff, ..., args = list(x = x, file = file)) } #' @export .export.rio_xlsx <- function(file, x, ...) { .docall(writexl::write_xlsx, ..., args = list(x = x, path = file)) } #' @export .export.rio_ods <- function(file, x, ...) { .check_pkg_availability("readODS") .docall(readODS::write_ods, ..., args = list(x = x, path = file)) } #' @export .export.rio_fods <- function(file, x, ...) { .check_pkg_availability("readODS") .docall(readODS::write_fods, ..., args = list(x = x, path = file)) } #' @export .export.rio_html <- function(file, x, ...) { .check_pkg_availability("xml2") html <- xml2::read_html("\nR Exported Data\n\n\n") bod <- xml2::xml_children(html)[[2]] if (is.data.frame(x)) { x <- list(x) } for (i in seq_along(x)) { x[[i]][] <- lapply(x[[i]], as.character) x[[i]][] <- lapply(x[[i]], escape_xml) names(x[[i]]) <- escape_xml(names(x[[i]])) tab <- xml2::xml_add_child(bod, "table") # add header row invisible(xml2::xml_add_child(tab, xml2::read_xml(paste0(twrap(paste0(twrap(names(x[[i]]), "th"), collapse = ""), "tr"), "\n")))) # add data for (j in seq_len(nrow(x[[i]]))) { xml2::xml_add_child(tab, xml2::read_xml(paste0(twrap(paste0(twrap(unlist(x[[i]][j, , drop = TRUE]), "td"), collapse = ""), "tr"), "\n"))) } } .docall(xml2::write_xml, ..., args = list(x = html, file = file)) } #' @export .export.rio_xml <- function(file, x, ...) { .check_pkg_availability("xml2") root <- "" xml <- xml2::read_xml(paste0("<", as.character(substitute(x)), ">\n\n")) att <- attributes(x)[!names(attributes(x)) %in% c("names", "row.names", "class")] for (a in seq_along(att)) { xml2::xml_attr(xml, names(att)[a]) <- att[[a]] } # remove illegal characters row.names(x) <- escape_xml(row.names(x)) colnames(x) <- escape_xml(colnames(x), ".") x[] <- lapply(x, escape_xml) # add data for (i in seq_len(nrow(x))) { thisrow <- xml2::xml_add_child(xml, "Observation") xml2::xml_attr(thisrow, "row.name") <- row.names(x)[i] for (j in seq_along(x)) { xml2::xml_add_child(thisrow, xml2::read_xml(paste0(twrap(x[i, j, drop = TRUE], names(x)[j]), "\n"))) } } .docall(xml2::write_xml, ..., args = list(x = xml, file = file)) } #' @export .export.rio_yml <- function(file, x, ...) { .check_pkg_availability("yaml") .docall(yaml::write_yaml, ..., args = list(x = x, file = file)) } #' @export .export.rio_clipboard <- function(file, x, row.names = FALSE, col.names = TRUE, sep = "\t", ...) { .check_pkg_availability("clipr") .docall(clipr::write_clip, ..., args = list(content = x, row.names = row.names, col.names = col.names, sep = sep)) } #' @export .export.rio_pzfx <- function(file, x, ..., row_names = FALSE) { .check_pkg_availability("pzfx") .docall(pzfx::write_pzfx, ..., args = list(x = x, path = file, row_names = row_names)) } #' @export .export.rio_parquet <- function(file, x, ...) { .docall(arrow::write_parquet, ..., args = list(x = x, sink = file)) } #' @export .export.rio_qs <- function(file, x, ...) { .check_pkg_availability("qs") .docall(qs::qsave, ..., args = list(x = x, file = file)) } rio/R/compression.R0000644000176200001440000000475514500016150013733 0ustar liggesusersfind_compress <- function(f) { if (grepl("zip$", f)) { return(list(file = sub("\\.zip$", "", f), compress = "zip")) } if (grepl("tar\\.gz$", f)) { return(list(file = sub("\\.tar\\.gz$", "", f), compress = "tar")) } if (grepl("tar$", f)) { return(list(file = sub("\\.tar$", "", f), compress = "tar")) } return(list(file = f, compress = NA_character_)) } compress_out <- function(cfile, filename, type = c("zip", "tar", "gzip", "bzip2", "xz")) { type <- ext <- match.arg(type) if (ext %in% c("gzip", "bzip2", "xz")) { ext <- paste0("tar") } if (missing(cfile)) { cfile <- paste0(filename, ".", ext) cfile2 <- paste0(basename(filename), ".", ext) } else { cfile2 <- basename(cfile) } filename <- normalizePath(filename) tmp <- tempfile() dir.create(tmp) on.exit(unlink(tmp, recursive = TRUE), add = TRUE) file.copy(from = filename, to = file.path(tmp, basename(filename)), overwrite = TRUE) wd <- getwd() on.exit(setwd(wd), add = TRUE) setwd(tmp) if (type == "zip") { o <- utils::zip(cfile2, files = basename(filename)) } else { if (type == "tar") { type <- "none" } o <- utils::tar(cfile2, files = basename(filename), compression = type) } setwd(wd) if (o != 0) { stop(sprintf("File compression failed for %s!", cfile)) } file.copy(from = file.path(tmp, cfile2), to = cfile, overwrite = TRUE) unlink(file.path(tmp, cfile2)) return(cfile) } parse_archive <- function(file, which, file_type, ...) { if (file_type == "zip") { file_list <- utils::unzip(file, list = TRUE)$Name extract_func <- utils::unzip } else if (file_type == "tar") { file_list <- utils::untar(file, list = TRUE) extract_func <- utils::untar } else { stop("Unsupported file_type. Use 'zip' or 'tar'.") } d <- tempfile() dir.create(d) if (missing(which)) { if (length(file_list) > 1) { warning(sprintf("%s archive contains multiple files. Attempting first file.", file_type)) } which <- 1 } if (is.numeric(which)) { extract_func(file, files = file_list[which], exdir = d) return(file.path(d, file_list[which])) } if (substring(which, 1, 1) != "^") { which2 <- paste0("^", which) } extract_func(file, files = file_list[grep(which2, file_list)[1]], exdir = d) return(file.path(d, which)) } rio/R/sysdata.rda0000644000176200001440000000426114502270161013405 0ustar liggesusersBZh91AY&SY8 o?@` V=֜ ɶ I!=L!5=4ڍ0&&&Ꞑzdi4EZ$%"BE"X6r ZkbŏRV9-,W)ُq-^IݓhL#z0!ldX(m\ýt)c0`9(e7xņkot"lR'UUTP[# / {gCHw` !",`,D@XP"P #"$- ",I ^+oƒ)7p(M@q_<> XPkK>ٛxV\]ysU&SJk̩nFMfXj f&W NNyW䑊=ChhȧV &ĢS8мD)Ê9D/*!'2ŝѹtIACG Bfq[>C،sGJϗ WZ*f\H`rjY%:Ϭ-"Jk*i&g)qjt}7諂ㆍze+# % HT)6 ,;zGWDDÓBQ#o NǤ؈ՌhAM`iG(*"6Jgr@4W9}ylOF`Eg `-IɄMyj)P~ſuAifVnxo_\"Ҧ_1rE8P8rio/R/remote_to_local.R0000644000176200001440000000514114476631364014555 0ustar liggesusersremote_to_local <- function(file, format) { if (missing(format)) { # handle google sheets urls if (grepl("docs\\.google\\.com/spreadsheets", file)) { file <- convert_google_url(file, export_as = "csv") format <- "csv" } else { # try to extract format from URL format <- try(get_info(file)$format, silent = TRUE) if (inherits(format, "try-error")) { format <- "TMP" } } } else { # handle google sheets urls if (grepl("docs\\.google\\.com/spreadsheets", file)) { format <- .standardize_format(format) if (format %in% c("csv", "tsv", "xlsx", "ods")) { file <- convert_google_url(file, export_as = format) format <- format } else { file <- convert_google_url(file, export_as = "csv") format <- "csv" } } else { format <- .standardize_format(format) } } # save file locally temp_file <- tempfile(fileext = paste0(".", format)) u <- curl::curl_fetch_memory(file) writeBin(object = u$content, con = temp_file) if (format == "TMP") { # try to extract format from curl's final URL format <- try(get_info(u$url)$format, silent = TRUE) if (inherits(format, "try-error")) { # try to extract format from headers h1 <- curl::parse_headers(u$headers) # check `Content-Disposition` header if (any(grepl("^Content-Disposition", h1))) { h <- h1[grep("filename", h1)] if (length(h)) { f <- regmatches(h, regexpr("(?<=\")(.*)(?", value, "") } escape_xml <- function(x, replacement = c("&", """, "<", ">", "'")) { stringi::stri_replace_all_fixed( str = stringi::stri_enc_toutf8(x), pattern = c("&", "\"", "<", ">", "'"), replacement = replacement, vectorize_all = FALSE ) } .check_pkg_availability <- function(pkg, lib.loc = NULL) { if (identical(find.package(pkg, quiet = TRUE, lib.loc = lib.loc), character(0))) { stop("Suggested package `", pkg, "` is not available. Please install it individually or use `install_formats()`", call. = FALSE) } return(invisible(NULL)) } .write_as_utf8 <- function(text, file, sep = "") { writeLines(enc2utf8(text), con = file, sep = sep, useBytes = TRUE) } .check_file <- function(file, single_only = TRUE) { ## check the `file` argument if (isTRUE(missing(file))) { ## for the case of export(iris, format = "csv") return(invisible(NULL)) } if (isFALSE(inherits(file, "character"))) { stop("Invalid `file` argument: must be character", call. = FALSE) } if (isFALSE(length(file) == 1) && single_only) { stop("Invalid `file` argument: `file` must be single", call. = FALSE) } invisible(NULL) } .create_directory_if_not_exists <- function(file) { R.utils::mkdirs(dirname(normalizePath(file, mustWork = FALSE))) invisible(NULL) } .create_outfiles <- function(file, x) { names_x <- names(x) if (length(file) == 1L) { if (!grepl("%s", file, fixed = TRUE)) { stop("'file' must have a %s placeholder") } if (is.null(names_x)) { return(sprintf(file, seq_along(x))) } if (any(nchar(names_x) == 0)) { stop("All elements of 'x' must be named or all must be unnamed") } if (anyDuplicated(names_x)) { stop("Names of elements in 'x' are not unique") } return(sprintf(file, names_x)) } if (length(x) != length(file)) { stop("'file' must be same length as 'x', or a single pattern with a %s placeholder") } if (anyDuplicated(file)) { stop("File names are not unique") } return(file) } rio/R/suggestions.R0000644000176200001440000000204014500577341013743 0ustar liggesusers#' @title Install rio's \sQuote{Suggests} Dependencies #' @description This function installs various \sQuote{Suggests} dependencies for rio that expand its support to the full range of support import and export formats. These packages are not installed or loaded by default in order to create a slimmer and faster package build, install, and load. #' @param \dots Additional arguments passed to [utils::install.packages()]. #' @return `NULL` #' @examples #' \donttest{ #' if (interactive()) { #' install_formats() #' } #' } #' @export install_formats <- function(...) { to_install <- uninstalled_formats() utils::install.packages(to_install, ...) invisible(TRUE) } uninstalled_formats <- function() { all_functions <- unlist(rio_formats[rio_formats$type == "suggest", c("import_function", "export_function")], use.names = FALSE) suggestions <- unique(stats::na.omit(stringi::stri_extract_first(all_functions, regex = "[a-zA-Z0-9\\.]+"))) ## which are not installed suggestions[!R.utils::isPackageInstalled(suggestions)] } rio/R/export.R0000644000176200001440000001711214500613454012714 0ustar liggesusers#' @rdname export #' @title Export #' @description Write data.frame to a file #' @param x A data frame or matrix to be written into a file. Exceptions to this rule are that `x` can be a list of data frames if the output file format is an OpenDocument Spreadsheet (.ods, .fods), Excel .xlsx workbook, .Rdata file, or HTML file, or a variety of R objects if the output file format is RDS or JSON. See examples.) To export a list of data frames to multiple files, use [export_list()] instead. #' @param file A character string naming a file. Must specify `file` and/or `format`. #' @param format An optional character string containing the file format, which can be used to override the format inferred from `file` or, in lieu of specifying `file`, a file with the symbol name of `x` and the specified file extension will be created. Must specify `file` and/or `format`. Shortcuts include: \dQuote{,} (for comma-separated values), \dQuote{;} (for semicolon-separated values), \dQuote{|} (for pipe-separated values), and \dQuote{dump} for [base::dump()]. #' @param \dots Additional arguments for the underlying export functions. This can be used to specify non-standard arguments. See examples. #' @return The name of the output file as a character string (invisibly). #' @details This function exports a data frame or matrix into a file with file format based on the file extension (or the manually specified format, if `format` is specified). #' #' The output file can be to a compressed directory, simply by adding an appropriate additional extensiont to the `file` argument, such as: \dQuote{mtcars.csv.tar}, \dQuote{mtcars.csv.zip}, or \dQuote{mtcars.csv.gz}. #' #' `export` supports many file formats. See the documentation for the underlying export functions for optional arguments that can be passed via `...` #' #' \itemize{ #' \item Comma-separated data (.csv), using [data.table::fwrite()] #' \item Pipe-separated data (.psv), using [data.table::fwrite()] #' \item Tab-separated data (.tsv), using [data.table::fwrite()] #' \item SAS (.sas7bdat), using [haven::write_sas()]. #' \item SAS XPORT (.xpt), using [haven::write_xpt()]. #' \item SPSS (.sav), using [haven::write_sav()] #' \item SPSS compressed (.zsav), using [haven::write_sav()] #' \item Stata (.dta), using [haven::write_dta()]. Note that variable/column names containing dots (.) are not allowed and will produce an error. #' \item Excel (.xlsx), using [writexl::write_xlsx()]. `x` can also be a list of data frames; the list entry names are used as sheet names. #' \item R syntax object (.R), using [base::dput()] (by default) or [base::dump()] (if `format = 'dump'`) #' \item Saved R objects (.RData,.rda), using [base::save()]. In this case, `x` can be a data frame, a named list of objects, an R environment, or a character vector containing the names of objects if a corresponding `envir` argument is specified. #' \item Serialized R objects (.rds), using [base::saveRDS()]. In this case, `x` can be any serializable R object. #' \item Serialized R objects (.qs), using [qs::qsave()], which is #' significantly faster than .rds. This can be any R #' object (not just a data frame). #' \item "XBASE" database files (.dbf), using [foreign::write.dbf()] #' \item Weka Attribute-Relation File Format (.arff), using [foreign::write.arff()] #' \item Fixed-width format data (.fwf), using [utils::write.table()] with `row.names = FALSE`, `quote = FALSE`, and `col.names = FALSE` #' \item gzip comma-separated data (.csv.gz), using [utils::write.table()] with `row.names = FALSE` #' \item [CSVY](https://github.com/csvy) (CSV with a YAML metadata header) using [data.table::fwrite()]. #' \item Apache Arrow Parquet (.parquet), using [arrow::write_parquet()] #' \item Feather R/Python interchange format (.feather), using [arrow::write_feather()] #' \item Fast storage (.fst), using [fst::write.fst()] #' \item JSON (.json), using [jsonlite::toJSON()]. In this case, `x` can be a variety of R objects, based on class mapping conventions in this paper: [https://arxiv.org/abs/1403.2805](https://arxiv.org/abs/1403.2805). #' \item Matlab (.mat), using [rmatio::write.mat()] #' \item OpenDocument Spreadsheet (.ods, .fods), using [readODS::write_ods()] or [readODS::write_fods()]. #' \item HTML (.html), using a custom method based on [xml2::xml_add_child()] to create a simple HTML table and [xml2::write_xml()] to write to disk. #' \item XML (.xml), using a custom method based on [xml2::xml_add_child()] to create a simple XML tree and [xml2::write_xml()] to write to disk. #' \item YAML (.yml), using [yaml::write_yaml()], default to write the content with UTF-8. Might not work on some older systems, e.g. default Windows locale for R <= 4.2. #' \item Clipboard export (on Windows and Mac OS), using [utils::write.table()] with `row.names = FALSE` #' } #' #' When exporting a data set that contains label attributes (e.g., if imported from an SPSS or Stata file) to a plain text file, [characterize()] can be a useful pre-processing step that records value labels into the resulting file (e.g., `export(characterize(x), "file.csv")`) rather than the numeric values. #' #' Use [export_list()] to export a list of dataframes to separate files. #' #' @examples #' ## For demo, a temp. file path is created with the file extension .csv #' csv_file <- tempfile(fileext = ".csv") #' ## .xlsx #' xlsx_file <- tempfile(fileext = ".xlsx") #' #' ## create CSV to import #' export(iris, csv_file) #' #' ## You can certainly export your data with the file name, which is not a variable: #' ## import(mtcars, "car_data.csv") #' #' ## pass arguments to the underlying function #' ## data.table::fwrite is the underlying function and `col.names` is an argument #' export(iris, csv_file, col.names = FALSE) #' #' ## export a list of data frames as worksheets #' export(list(a = mtcars, b = iris), xlsx_file) #' #' # NOT RECOMMENDED #' #' ## specify `format` to override default format #' export(iris, xlsx_file, format = "csv") ## That's confusing #' ## You can also specify only the format; in the following case #' ## "mtcars.dta" is written [also confusing] #' #' ## export(mtcars, format = "stata") #' @seealso [characterize()], [import()], [convert()], [export_list()] #' @export export <- function(x, file, format, ...) { .check_file(file, single_only = TRUE) if (missing(file) && missing(format)) { stop("Must specify 'file' and/or 'format'") } if (!missing(file)) { cfile <- file f <- find_compress(file) file <- f$file compress <- f$compress format <- ifelse(isFALSE(missing(format)), tolower(format), get_info(file)$input) } else { format <- .standardize_format(format) file <- paste0(as.character(substitute(x)), ".", format) compress <- NA_character_ } format <- .standardize_format(format) outfile <- file if (is.matrix(x) || inherits(x, "ArrowTabular")) { x <- as.data.frame(x) } if (!is.data.frame(x) && !format %in% c("xlsx", "html", "rdata", "rds", "json", "qs", "fods", "ods")) { stop("'x' is not a data.frame or matrix", call. = FALSE) } .create_directory_if_not_exists(file = file) ## fix 347 if (format %in% c("gz", "gzip")) { format <- get_info(tools::file_path_sans_ext(file, compression = FALSE))$format } class(file) <- c(paste0("rio_", format), class(file)) .export(file = file, x = x, ...) if (!is.na(compress)) { cfile <- compress_out(cfile = cfile, filename = file, type = compress) unlink(file) return(invisible(cfile)) } invisible(unclass(outfile)) } rio/R/convert.R0000644000176200001440000000352214476051106013055 0ustar liggesusers#' @title Convert from one file format to another #' @description This function constructs a data frame from a data file using [import()] and uses [export()] to write the data to disk in the format indicated by the file extension. #' @param in_file A character string naming an input file. #' @param out_file A character string naming an output file. #' @param in_opts A named list of options to be passed to [import()]. #' @param out_opts A named list of options to be passed to [export()]. #' @return A character string containing the name of the output file (invisibly). #' @examples #' ## For demo, a temp. file path is created with the file extension .dta (Stata) #' dta_file <- tempfile(fileext = ".dta") #' ## .csv #' csv_file <- tempfile(fileext = ".csv") #' ## .xlsx #' xlsx_file <- tempfile(fileext = ".xlsx") #' #' #' ## Create a Stata data file #' export(mtcars, dta_file) #' #' ## convert Stata to CSV and open converted file #' convert(dta_file, csv_file) #' import(csv_file) #' #' ## correct an erroneous file format #' export(mtcars, xlsx_file, format = "tsv") ## DON'T DO THIS #' ## import(xlsx_file) ## ERROR #' ## convert the file by specifying `in_opts` #' convert(xlsx_file, xlsx_file, in_opts = list(format = "tsv")) #' import(xlsx_file) #' #' ## convert from the command line: #' ## Rscript -e "rio::convert('mtcars.dta', 'mtcars.csv')" #' @seealso [Luca Braglia](https://lbraglia.github.io/) has created a Shiny app called [rioweb](https://github.com/lbraglia/rioweb) that provides access to the file conversion features of rio through a web browser. #' @export convert <- function(in_file, out_file, in_opts=list(), out_opts=list()) { if (missing(out_file)) { stop("'outfile' is missing with no default") } invisible(do.call("export", c(list(file = out_file, x = do.call("import", c(list(file=in_file), in_opts))), out_opts))) } rio/R/gather_attrs.R0000644000176200001440000000504114500666514014065 0ustar liggesusers#' @rdname gather_attrs #' @title Gather attributes from data frame variables #' @description `gather_attrs` moves variable-level attributes to the data frame level and `spread_attrs` reverses that operation. #' @details [import()] attempts to standardize the return value from the various import functions to the extent possible, thus providing a uniform data structure regardless of what import package or function is used. It achieves this by storing any optional variable-related attributes at the variable level (i.e., an attribute for `mtcars$mpg` is stored in `attributes(mtcars$mpg)` rather than `attributes(mtcars)`). `gather_attrs` moves these to the data frame level (i.e., in `attributes(mtcars)`). `spread_attrs` moves attributes back to the variable level. #' @param x A data frame. #' @return `x`, with variable-level attributes stored at the data frame level. #' @seealso [import()], [characterize()] #' @export gather_attrs <- function(x) { if (!inherits(x, "data.frame")) { stop("'x' is not a data.frame") } dfattrs <- attributes(x) if ("label" %in% names(dfattrs)) { names(dfattrs)[names(dfattrs) == "label"] <- "title" } varattrs <- rep(list(list()), length(x)) for (i in seq_along(x)) { a <- attributes(x[[i]]) varattrs[[i]] <- a[!names(a) %in% c("levels", "class")] attr(x[[i]], "label") <- NULL if (any(grepl("labelled", class(x[[i]])))) { x[[i]] <- haven::zap_labels(x[[i]]) } f <- grep("^format", names(attributes(x[[i]])), value = TRUE) if (length(f)) { attr(x[[i]], f) <- NULL } rm(f) } if (any(vapply(varattrs, length, integer(1)))) { attrnames <- sort(unique(unlist(lapply(varattrs, names)))) outattrs <- stats::setNames(lapply(attrnames, function(z) { stats::setNames(lapply(varattrs, `[[`, z), names(x)) }), attrnames) attributes(x) <- c(dfattrs, outattrs) } x } #' @rdname gather_attrs #' @export spread_attrs <- function(x) { if (!inherits(x, "data.frame")) { stop("'x' is not a data.frame") } dfattrs <- attributes(x) d_level_attrs <- names(dfattrs) %in% c("row.names", "class", "names", "notes", "title") varattrs <- dfattrs[!d_level_attrs] for (i in seq_along(x)) { a <- attributes(x[[i]]) attributes(x[[i]]) <- c(a, lapply(varattrs, `[[`, i)) } if ("title" %in% names(dfattrs)) { names(dfattrs)[names(dfattrs) == "title"] <- "label" } attributes(x) <- dfattrs[d_level_attrs] x } rio/R/convert_google_url.R0000644000176200001440000000104314047423624015271 0ustar liggesusersconvert_google_url <- function(url, export_as = "csv") { ## convert a google sheets url to google csv export URL ## extract the doc-id and append /export?format = csv to it. (default) google_key <- regmatches(url, regexpr("[[:alnum:]_-]{30,}", url)) if (grepl('gid=[[:digit:]]+', url)) { gidpart <- paste0(regmatches(url, regexpr("gid=[[:digit:]]+", url))) } else { gidpart <- "gid=0" } return(paste0('https://docs.google.com/spreadsheets/d/', google_key, '/export?', gidpart, '&format=', export_as)) } rio/R/fwf2.R0000644000176200001440000000342614500606254012242 0ustar liggesusersread.fwf2 <- function(file, widths, header = FALSE, sep = "\t", skip = 0, n = -1, quote = "", stringsAsFactors = FALSE, ...) { doone <- function(x) { x <- substring(x, first, last) x[!nzchar(x)] <- NA_character_ paste0(x, collapse = sep) } if (is.list(widths)) { recordlength <- length(widths) widths <- do.call("c", widths) } else { recordlength <- 1L } drop <- (widths < 0L) widths <- abs(widths) if (is.character(file)) { file <- file(file, "rt") on.exit(close(file), add = TRUE) } else if (!isOpen(file)) { open(file, "rt") on.exit(close(file), add = TRUE) } if (skip) { readLines(file, n = skip) } if (header) { headerline <- readLines(file, n = 1L) text[1] <- headerline } raw <- readLines(file, n = n) nread <- length(raw) if (recordlength > 1L && nread %% recordlength) { raw <- raw[1L:(nread - nread %% recordlength)] warning(sprintf( ngettext( nread %% recordlength, "last record incomplete, %d line discarded", "last record incomplete, %d lines discarded" ), nread %% recordlength ), domain = NA) } if (recordlength > 1L) { raw <- matrix(raw, nrow = recordlength) raw <- apply(raw, 2L, paste, collapse = "") } st <- c(1L, 1L + cumsum(widths)) first <- st[-length(st)][!drop] last <- cumsum(widths)[!drop] if (header) { text <- c(headerline, vapply(raw, doone, character(1))) } else { text <- vapply(raw, doone, character(1)) } .docall(utils::read.table, ..., args = list(text = text, header = header, sep = sep, quote = quote, stringsAsFactors = stringsAsFactors)) } rio/R/characterize.R0000644000176200001440000000554214476051106014045 0ustar liggesusers#' @rdname characterize #' @title Character conversion of labelled data #' @description Convert labelled variables to character or factor #' @param x A vector or data frame. #' @param coerce_character A logical indicating whether to additionally coerce character columns to factor (in `factorize`). Default `FALSE`. #' @param \dots additional arguments passed to methods #' @details `characterize` converts a vector with a `labels` attribute of named levels into a character vector. `factorize` does the same but to factors. This can be useful at two stages of a data workflow: (1) importing labelled data from metadata-rich file formats (e.g., Stata or SPSS), and (2) exporting such data to plain text files (e.g., CSV) in a way that preserves information. #' @return a character vector (for `characterize`) or factor vector (for `factorize`) #' @examples #' ## vector method #' x <- structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3)) #' characterize(x) #' factorize(x) #' #' ## data frame method #' x <- data.frame(v1 = structure(1:4, labels = c("A" = 1, "B" = 2, "C" = 3)), #' v2 = structure(c(1,0,0,1), labels = c("foo" = 0, "bar" = 1))) #' str(factorize(x)) #' str(characterize(x)) #' #' ## Application #' csv_file <- tempfile(fileext = ".csv") #' ## comparison of exported file contents #' import(export(x, csv_file)) #' import(export(factorize(x), csv_file)) #' @seealso [gather_attrs()] #' @export characterize <- function(x, ...) { UseMethod("characterize") } #' @rdname characterize #' @export factorize <- function(x, ...) { UseMethod("factorize") } #' @rdname characterize #' @export characterize.default <- function(x, ...) { # retain variable label, if present if (!is.null(attributes(x)[["label"]])) { varlab <- attributes(x)[["label"]] } else { varlab <- NULL } if (!is.null(attributes(x)[["labels"]])) { x <- as.character(factorize(x, ...)) if (!is.null(varlab)) { attr(x, "label") <- varlab } } return(x) } #' @rdname characterize #' @export characterize.data.frame <- function(x, ...) { x[] <- lapply(x, characterize, ...) x } #' @rdname characterize #' @export factorize.default <- function(x, coerce_character=FALSE, ...) { # retain variable label, if present if (!is.null(attributes(x)[["label"]])) { varlab <- attributes(x)[["label"]] } else { varlab <- NULL } if (!is.null(attributes(x)[["labels"]])) { x <- factor(x, attributes(x)[["labels"]], names(attributes(x)[["labels"]]), ...) } else if (is.character(x) && isTRUE(coerce_character)) { levs <- sort(unique(x)) x <- factor(x, levs) } if (!is.null(varlab)) { attr(x, "label") <- varlab } return(x) } #' @rdname characterize #' @export factorize.data.frame <- function(x, ...) { x[] <- lapply(x, factorize, ...) x } rio/R/rio.R0000644000176200001440000000305214476051106012164 0ustar liggesusers#' @docType package #' @name rio #' @title A Swiss-Army Knife for Data I/O #' @description The aim of rio is to make data file input and output as easy as possible. [export()] and [import()] serve as a Swiss-army knife for painless data I/O for data from almost any file format by inferring the data structure from the file extension, natively reading web-based data sources, setting reasonable defaults for import and export, and relying on efficient data import and export packages. An additional convenience function, [convert()], provides a simple method for converting between file types. #' #' Note that some of rio's functionality is provided by \sQuote{Suggests} dependendencies, meaning they are not installed by default. Use [install_formats()] to make sure these packages are available for use. #' #' @examples #' # export #' library("datasets") #' export(mtcars, csv_file <- tempfile(fileext = ".csv")) # comma-separated values #' export(mtcars, rds_file <- tempfile(fileext = ".rds")) # R serialized #' export(mtcars, sav_file <- tempfile(fileext = ".sav")) # SPSS #' #' # import #' x <- import(csv_file) #' y <- import(rds_file) #' z <- import(sav_file) #' #' # convert sav (SPSS) to dta (Stata) #' convert(sav_file, dta_file <- tempfile(fileext = ".dta")) #' #' # cleanup #' unlink(c(csv_file, rds_file, sav_file, dta_file)) #' #' @references #' [GREA](https://github.com/Stan125/GREA) provides an RStudio add-in to import data using rio. #' @seealso [import()], [import_list()], [export()], [export_list()], [convert()], [install_formats()] "_PACKAGE" rio/R/set_class.R0000644000176200001440000000214514502270161013347 0ustar liggesusersset_class <- function(x, class = NULL) { if (is.null(class)) { return(x) } if ("data.table" %in% class) { return(.ensure_data_table(x)) } if (any(c("tibble", "tbl_df", "tbl") %in% class)) { return(.ensure_tibble(x)) } if (any(c("arrow", "arrow_table") %in% class)) { ## because setclass can be used without import, must check again .check_pkg_availability("arrow") return(.ensure_arrow(x)) } return(.ensure_data_frame(x)) } .ensure_arrow <- function(x) { if (inherits(x, "ArrowTabular")) { return(x) } return(arrow::arrow_table(x)) } .ensure_data_table <- function(x) { if (inherits(x, "data.table")) { return(x) } return(data.table::as.data.table(x)) } .ensure_tibble <- function(x) { if (inherits(x, "tbl")) { return(x) } return(tibble::as_tibble(x)) } .ensure_data_frame <- function(x) { out <- structure(x, class = "data.frame") if (!length(rownames(out))) { rownames(out) <- as.character(seq_len(length(out[, 1L, drop = TRUE]))) } return(out) } rio/R/export_list.R0000644000176200001440000000624514500016150013742 0ustar liggesusers#' @title Export list of data frames to files #' @description Use [export()] to export a list of data frames to a vector of file names or a filename pattern. #' @param x A list of data frames to be written to files. #' @param file A character vector string containing a single file name with a `\%s` wildcard placeholder, or a vector of file paths for multiple files to be imported. If `x` elements are named, these will be used in place of `\%s`, otherwise numbers will be used; all elements must be named for names to be used. #' @param archive character. Either empty string (default) to save files in current #' directory, a path to a (new) directory, or a .zip/.tar file to compress all #' files into an archive. #' @param \dots Additional arguments passed to [export()]. #' @return The name(s) of the output file(s) as a character vector (invisibly). #' @details [export()] can export a list of data frames to a single multi-dataset file (e.g., an Rdata or Excel .xlsx file). Use `export_list` to export such a list to *multiple* files. #' @examples #' ## For demo, a temp. file path is created with the file extension .xlsx #' xlsx_file <- tempfile(fileext = ".xlsx") #' export( #' list( #' mtcars1 = mtcars[1:10, ], #' mtcars2 = mtcars[11:20, ], #' mtcars3 = mtcars[21:32, ] #' ), #' xlsx_file #' ) #' #' # import a single file from multi-object workbook #' import(xlsx_file, sheet = "mtcars1") #' # import all worksheets, the return value is a list #' import_list(xlsx_file) #' library('datasets') #' export(list(mtcars1 = mtcars[1:10,], #' mtcars2 = mtcars[11:20,], #' mtcars3 = mtcars[21:32,]), #' xlsx_file <- tempfile(fileext = ".xlsx") #' ) #' #' # import all worksheets #' list_of_dfs <- import_list(xlsx_file) #' #' # re-export as separate named files #' #' ## export_list(list_of_dfs, file = c("file1.csv", "file2.csv", "file3.csv")) #' #' # re-export as separate files using a name pattern; using the names in the list #' ## This will be written as "mtcars1.csv", "mtcars2.csv", "mtcars3.csv" #' #' ## export_list(list_of_dfs, file = "%s.csv") #' @seealso [import()], [import_list()], [export()] #' @export export_list <- function(x, file, archive = "", ...) { .check_file(file, single_only = FALSE) archive_format <- find_compress(archive) if (inherits(x, "data.frame")) { stop("'x' must be a list. Perhaps you want export()?") } outfiles <- .create_outfiles(file, x) if (is.na(archive_format$compress) && archive_format$file != "") { outfiles <- file.path(archive_format$file, outfiles) } outfiles_normalized <- normalizePath(outfiles, mustWork = FALSE) out <- list() for (f in seq_along(x)) { out[[f]] <- try(export(x[[f]], file = outfiles_normalized[f], ...), silent = TRUE) if (inherits(out[[f]], "try-error")) { warning(sprintf("Export failed for element %d, filename: %s", f, outfiles[f])) } } if (!is.na(archive_format$compress)) { .create_directory_if_not_exists(archive) compress_out(archive, outfiles_normalized) unlink(outfiles_normalized) return(invisible(archive)) } return(invisible(outfiles)) } rio/R/onLoad.R0000644000176200001440000000053614476051106012613 0ustar liggesusers.onAttach <- function(libname, pkgname) { if (interactive()) { w <- uninstalled_formats() if (length(w)) { msg <- "The following rio suggested packages are not installed: %s\nUse 'install_formats()' to install them" packageStartupMessage(sprintf(msg, paste0(sQuote(w), collapse = ", "))) } } } rio/R/import.R0000644000176200001440000002422614502270161012705 0ustar liggesusers#' @rdname import #' @title Import #' @description Read in a data.frame from a file. Exceptions to this rule are Rdata, RDS, and JSON input file formats, which return the originally saved object without changing its class. #' @param file A character string naming a file, URL, or single-file .zip or .tar archive. #' @param format An optional character string code of file format, which can be used to override the format inferred from `file`. Shortcuts include: \dQuote{,} (for comma-separated values), \dQuote{;} (for semicolon-separated values), and \dQuote{|} (for pipe-separated values). #' @param setclass An optional character vector specifying one or more classes #' to set on the import. By default, the return object is always a #' \dQuote{data.frame}. Allowed values include \dQuote{tbl_df}, \dQuote{tbl}, or #' \dQuote{tibble} (if using tibble), \dQuote{arrow}, \dQuote{arrow_table} (if using arrow table; the suggested package `arrow` must be installed) or \dQuote{data.table} (if using #' data.table). Other values are ignored, such that a data.frame is returned. #' The parameter takes precedents over parameters in \dots which set a different class. #' @param which This argument is used to control import from multi-object files; as a rule `import` only ever returns a single data frame (use [import_list()] to import multiple data frames from a multi-object file). If `file` is a compressed directory, `which` can be either a character string specifying a filename or an integer specifying which file (in locale sort order) to extract from the compressed directory. For Excel spreadsheets, this can be used to specify a sheet name or number. For .Rdata files, this can be an object name. For HTML files, it identifies which table to extract (from document order). Ignored otherwise. A character string value will be used as a regular expression, such that the extracted file is the first match of the regular expression against the file names in the archive. #' @param \dots Additional arguments passed to the underlying import functions. For example, this can control column classes for delimited file types, or control the use of haven for Stata and SPSS or readxl for Excel (.xlsx) format. See details below. #' @return A data frame. If `setclass` is used, this data frame may have additional class attribute values, such as \dQuote{tibble} or \dQuote{data.table}. #' @details This function imports a data frame or matrix from a data file with the file format based on the file extension (or the manually specified format, if `format` is specified). #' #' `import` supports the following file formats: #' #' \itemize{ #' \item Comma-separated data (.csv), using [data.table::fread()] #' \item Pipe-separated data (.psv), using [data.table::fread()] #' \item Tab-separated data (.tsv), using [data.table::fread()] #' \item SAS (.sas7bdat), using [haven::read_sas()] #' \item SAS XPORT (.xpt), using [haven::read_xpt()] #' \item SPSS (.sav), using [haven::read_sav()] #' \item SPSS compressed (.zsav), using [haven::read_sav()]. #' \item Stata (.dta), using [haven::read_dta()] #' \item SPSS Portable Files (.por), using [haven::read_por()]. #' \item Excel (.xls and .xlsx), using [readxl::read_xlsx()] or [readxl::read_xls()]. Use `which` to specify a sheet number. #' \item R syntax object (.R), using [base::dget()] #' \item Saved R objects (.RData,.rda), using [base::load()] for single-object .Rdata files. Use `which` to specify an object name for multi-object .Rdata files. This can be any R object (not just a data frame). #' \item Serialized R objects (.rds), using [base::readRDS()]. This can be any R object (not just a data frame). #' \item Serialized R objects (.qs), using [qs::qread()], which is #' significantly faster than .rds. This can be any R #' object (not just a data frame). #' \item Epiinfo (.rec), using [foreign::read.epiinfo()] #' \item Minitab (.mtp), using [foreign::read.mtp()] #' \item Systat (.syd), using [foreign::read.systat()] #' \item "XBASE" database files (.dbf), using [foreign::read.dbf()] #' \item Weka Attribute-Relation File Format (.arff), using [foreign::read.arff()] #' \item Data Interchange Format (.dif), using [utils::read.DIF()] #' \item Fortran data (no recognized extension), using [utils::read.fortran()] #' \item Fixed-width format data (.fwf), using a faster version of [utils::read.fwf()] that requires a `widths` argument and by default in rio has `stringsAsFactors = FALSE` #' \item gzip comma-separated data (.csv.gz), using [utils::read.table()] with `row.names = FALSE` and `stringsAsFactors = FALSE` #' \item [CSVY](https://github.com/csvy) (CSV with a YAML metadata header) using [data.table::fread()]. #' \item Apache Arrow Parquet (.parquet), using [arrow::read_parquet()] #' \item Feather R/Python interchange format (.feather), using [arrow::read_feather()] #' \item Fast storage (.fst), using [fst::read.fst()] #' \item JSON (.json), using [jsonlite::fromJSON()] #' \item Matlab (.mat), using [rmatio::read.mat()] #' \item EViews (.wf1), using [hexView::readEViews()] #' \item OpenDocument Spreadsheet (.ods, .fods), using [readODS::read_ods()] or [readODS::read_fods()]. Use `which` to specify a sheet number. #' \item Single-table HTML documents (.html), using [xml2::read_html()]. There is no standard HTML table and we have only tested this with HTML tables exported with this package. HTML tables will only be read correctly if the HTML file can be converted to a list via [xml2::as_list()]. This import feature is not robust, especially for HTML tables in the wild. Please use a proper web scraping framework, e.g. `rvest`. #' \item Shallow XML documents (.xml), using [xml2::read_xml()]. The data structure will only be read correctly if the XML file can be converted to a list via [xml2::as_list()]. #' \item YAML (.yml), using [yaml::yaml.load()] #' \item Clipboard import, using [utils::read.table()] with `row.names = FALSE` #' \item Google Sheets, as Comma-separated data (.csv) #' \item GraphPad Prism (.pzfx) using [pzfx::read_pzfx()] #' } #' #' `import` attempts to standardize the return value from the various import functions to the extent possible, thus providing a uniform data structure regardless of what import package or function is used. It achieves this by storing any optional variable-related attributes at the variable level (i.e., an attribute for `mtcars$mpg` is stored in `attributes(mtcars$mpg)` rather than `attributes(mtcars)`). If you would prefer these attributes to be stored at the data.frame-level (i.e., in `attributes(mtcars)`), see [gather_attrs()]. #' #' After importing metadata-rich file formats (e.g., from Stata or SPSS), it may be helpful to recode labelled variables to character or factor using [characterize()] or [factorize()] respectively. #' #' @note For csv and txt files with row names exported from [export()], it may be helpful to specify `row.names` as the column of the table which contain row names. See example below. #' @examples #' ## For demo, a temp. file path is created with the file extension .csv #' csv_file <- tempfile(fileext = ".csv") #' ## .xlsx #' xlsx_file <- tempfile(fileext = ".xlsx") #' ## create CSV to import #' export(iris, csv_file) #' ## specify `format` to override default format: see export() #' export(iris, xlsx_file, format = "csv") #' #' ## basic #' import(csv_file) #' #' ## You can certainly import your data with the file name, which is not a variable: #' ## import("starwars.csv"); import("mtcars.xlsx") #' #' ## Override the default format #' ## import(xlsx_file) # Error, it is actually not an Excel file #' import(xlsx_file, format = "csv") #' #' ## import CSV as a `data.table` #' import(csv_file, setclass = "data.table") #' #' ## import CSV as a tibble (or "tbl_df") #' import(csv_file, setclass = "tbl_df") #' #' ## pass arguments to underlying import function #' ## data.table::fread is the underlying import function and `nrows` is its argument #' import(csv_file, nrows = 20) #' #' ## data.table::fread has an argument `data.table` to set the class explicitely to data.table. The #' ## argument setclass, however, takes precedents over such undocumented features. #' class(import(csv_file, setclass = "tibble", data.table = TRUE)) #' #' ## the default import class can be set with options(rio.import.class = "data.table") #' ## option(rio.import.class = "tibble"), or option(rio.import.class = "arrow") #' @seealso [import_list()], [characterize()], [gather_attrs()], [export()], [convert()] #' @export import <- function(file, format, setclass = getOption("rio.import.class", "data.frame"), which, ...) { if (setclass %in% c("arrow", "arrow_table")) { .check_pkg_availability("arrow") } .check_file(file, single_only = TRUE) if (R.utils::isUrl(file)) { file <- remote_to_local(file, format = format) } if ((file != "clipboard") && !file.exists(file)) { stop("No such file: ", file, call. = FALSE) } if (grepl("\\.zip$", file)) { if (missing(which)) { file <- parse_archive(file, file_type = "zip") } else { file <- parse_archive(file, which = which, file_type = "zip") } } else if (grepl("\\.tar", file)) { if (missing(which)) { which <- 1 } file <- parse_archive(file, which = which, file_type = "tar") } if (missing(format)) { format <- get_info(file)$format if (format %in% c("gz", "gzip")) { format <- get_info(tools::file_path_sans_ext(file, compression = FALSE))$format # file <- gzfile(file) } } else { ## format such as "|" format <- .standardize_format(format) } args_list <- list(...) class(file) <- c(paste0("rio_", format), class(file)) if (missing(which)) { x <- .import(file = file, ...) } else { x <- .import(file = file, which = which, ...) } # if R serialized object, just return it without setting object class if (inherits(file, c("rio_rdata", "rio_rds", "rio_json", "rio_qs")) && !inherits(x, "data.frame")) { return(x) } # otherwise, make sure it's a data frame (or requested class) return(set_class(x, class = setclass)) } rio/R/import_methods.R0000644000176200001440000003565314502270161014436 0ustar liggesusers.docall <- function(.fcn, ..., args = NULL, alwaysArgs = NULL, .functions = list(.fcn), .ignoreUnusedArgs = TRUE) { ## the same as R.utils::doCall, only with default option R.utils::doCall(.fcn = .fcn, ..., args = args, alwaysArgs = alwaysArgs, .functions = .functions, .ignoreUnusedArgs = getOption("rio.ignoreunusedargs", default = TRUE)) } .remap_tidy_convention <- function(func, file, which, header, ...) { dots <- list(...) if ("path" %in% names(dots)) { dots[["path"]] <- NULL } if ("sheet" %in% names(dots)) { which <- dots[["sheet"]] dots[["sheet"]] <- NULL } if ("col_names" %in% names(dots)) { header <- dots[["col_names"]] dots[["col_names"]] <- NULL } .docall(func, args = c(dots, list(path = file, sheet = which, col_names = header))) } import_delim <- function(file, which = 1, sep = "auto", header = "auto", stringsAsFactors = FALSE, data.table = FALSE, ...) { .docall(data.table::fread, ..., args = list(input = file, sep = sep, header = header, stringsAsFactors = stringsAsFactors, data.table = data.table)) } #' @export .import.rio_dat <- function(file, which = 1, ...) { message(sprintf("Ambiguous file format ('.dat'), but attempting 'data.table::fread(\"%s\")'", file)) import_delim(file = file, ...) } #' @export .import.rio_tsv <- function(file, sep = "auto", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c("\t", "auto")) "." else ",", ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "tsv will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = sep, dec = dec, ...) } #' @export .import.rio_txt <- function(file, sep = "auto", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c(",", "auto")) "." else ",", ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "txt will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = sep, dec = dec, ...) } #' @export .import.rio_csv <- function(file, sep = ",", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c(",", "auto")) "." else ",", ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "csv will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = if (sep == ",") "auto" else sep, dec = dec, ...) } #' @export .import.rio_csv2 <- function(file, sep = ";", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c(";", "auto")) "," else ".", ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "csv2 will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = if (sep == ";") "auto" else sep, dec = dec, ...) } #' @export .import.rio_csvy <- function(file, sep = ",", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c(",", "auto")) "." else ",", yaml = TRUE, ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "csvy will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = if (sep == ",") "auto" else sep, dec = dec, yaml = yaml, ...) } #' @export .import.rio_psv <- function(file, sep = "|", which = 1, fread = lifecycle::deprecated(), dec = if (sep %in% c("|", "auto")) "." else ",", ...) { if (lifecycle::is_present(fread)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(fread)", details = "psv will always be read by `data.table:fread()`. The parameter `fread` will be dropped in v2.0.0.") } import_delim(file = file, sep = if (sep == "|") "auto" else sep, dec = dec, ...) } #' @export .import.rio_fwf <- function(file, which = 1, widths, header = FALSE, col.names, comment = "#", readr = lifecycle::deprecated(), progress = getOption("verbose", FALSE), ...) { if (lifecycle::is_present(readr)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(readr)", details = "fwt will always be read without `readr`. The parameter `readr` will be dropped in v2.0.0.") } if (missing(widths)) { stop("Import of fixed-width format data requires a 'widths' argument. See ? read.fwf().") } if (!missing(col.names)) { read.fwf2(file = file, widths = widths, header = header, col.names = col.names, ...) } else { read.fwf2(file = file, widths = widths, header = header, ...) } } #' @export .import.rio_r <- function(file, which = 1, ...) { .docall(dget, ..., args = list(file = file)) } #' @export .import.rio_dump <- function(file, which = 1, envir = new.env(), ...) { source(file = file, local = envir) if (missing(which)) { if (length(ls(envir)) > 1) { warning("Dump file contains multiple objects. Returning first object.") } which <- 1 } if (is.numeric(which)) { get(ls(envir)[which], envir) } else { get(ls(envir)[grep(which, ls(envir))[1]], envir) } } #' @export .import.rio_rds <- function(file, which = 1, ...) { readRDS(file = file) } #' @export .import.rio_rdata <- function(file, which = 1, envir = new.env(), ...) { load(file = file, envir = envir) if (missing(which)) { if (length(ls(envir)) > 1) { warning("Rdata file contains multiple objects. Returning first object.") } which <- 1 } if (is.numeric(which)) { get(ls(envir)[which], envir) } else { get(ls(envir)[grep(which, ls(envir))[1]], envir) } } #' @export .import.rio_rda <- .import.rio_rdata #' @export .import.rio_feather <- function(file, which = 1, ...) { .check_pkg_availability("arrow") .docall(arrow::read_feather, ..., args = list(file = file)) } #' @export .import.rio_fst <- function(file, which = 1, ...) { .check_pkg_availability("fst") .docall(fst::read.fst, ..., args = list(path = file)) } #' @export .import.rio_matlab <- function(file, which = 1, ...) { .check_pkg_availability("rmatio") rmatio::read.mat(filename = file) } #' @export .import.rio_dta <- function(file, haven = lifecycle::deprecated(), convert.factors = lifecycle::deprecated(), which = 1, ...) { if (lifecycle::is_present(haven) || lifecycle::is_present(convert.factors)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(haven)", details = "dta will always be read by `haven`. The parameter `haven` will be dropped in v2.0.0.") } standardize_attributes(.docall(haven::read_dta, ..., args = list(file = file))) } #' @export .import.rio_dbf <- function(file, which = 1, as.is = TRUE, ...) { .docall(foreign::read.dbf, ..., args = list(file = file, as.is = as.is)) } #' @export .import.rio_dif <- function(file, which = 1, ...) { .docall(utils::read.DIF, ..., args = list(file = file)) } #' @export .import.rio_sav <- function(file, which = 1, haven = lifecycle::deprecated(), to.data.frame = lifecycle::deprecated(), use.value.labels = lifecycle::deprecated(), ...) { if (lifecycle::is_present(haven) || lifecycle::is_present(to.data.frame) || lifecycle::is_present(use.value.labels)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(haven)", details = "sav will always be read by `haven`. The parameter `haven` will be dropped in v2.0.0.") } standardize_attributes(.docall(haven::read_sav, ..., args = list(file = file))) } #' @export .import.rio_zsav <- function(file, which = 1, ...) { standardize_attributes(.docall(haven::read_sav, ..., args = list(file = file))) } #' @export .import.rio_spss <- function(file, which = 1, ...) { standardize_attributes(.docall(haven::read_por, ..., args = list(file = file))) } #' @export .import.rio_sas7bdat <- function(file, which = 1, column.labels = FALSE, ...) { standardize_attributes(.docall(haven::read_sas, ..., args = list(data_file = file))) } #' @export .import.rio_xpt <- function(file, which = 1, haven = lifecycle::deprecated(), ...) { if (lifecycle::is_present(haven)) { lifecycle::deprecate_warn(when = "0.5.31", what = "import(haven)", details = "xpt will always be read by `haven`. The parameter `haven` will be dropped in v2.0.0.") } standardize_attributes(.docall(haven::read_xpt, ..., args = list(file = file))) } #' @export .import.rio_mtp <- function(file, which = 1, ...) { .docall(foreign::read.mtp, ..., args = list(file = file)) } #' @export .import.rio_syd <- function(file, which = 1, ...) { .docall(foreign::read.systat, ..., args = list(file = file, to.data.frame = TRUE)) } #' @export .import.rio_json <- function(file, which = 1, ...) { .check_pkg_availability("jsonlite") .docall(jsonlite::fromJSON, ..., args = list(txt = file)) } #' @export .import.rio_rec <- function(file, which = 1, ...) { .docall(foreign::read.epiinfo, ..., args = list(file = file)) } #' @export .import.rio_arff <- function(file, which = 1, ...) { .docall(foreign::read.arff, ..., args = list(file = file)) } #' @export .import.rio_xls <- function(file, which = 1, header = TRUE, ...) { .remap_tidy_convention(readxl::read_xls, file = file, which = which, header = header, ...) } #' @export .import.rio_xlsx <- function(file, which = 1, header = TRUE, readxl = lifecycle::deprecated(), ...) { if (lifecycle::is_present(readxl)) { lifecycle::deprecate_warn( when = "0.5.31", what = "import(readxl)", details = "xlsx will always be read by `readxl`. The parameter `readxl` will be dropped in v2.0.0." ) } .remap_tidy_convention(readxl::read_xlsx, file = file, which = which, header = header, ...) } #' @export .import.rio_fortran <- function(file, which = 1, style, ...) { if (missing(style)) { stop("Import of Fortran format data requires a 'style' argument. See ? utils::read.fortran().") } .docall(utils::read.fortran, ..., args = list(file = file, format = style)) } #' @export .import.rio_ods <- function(file, which = 1, header = TRUE, ...) { .check_pkg_availability("readODS") .remap_tidy_convention(readODS::read_ods, file = file, which = which, header = header, ...) } #' @export .import.rio_fods <- function(file, which = 1, header = TRUE, ...) { .check_pkg_availability("readODS") .remap_tidy_convention(readODS::read_fods, file = file, which = which, header = header, ...) } #' @export .import.rio_xml <- function(file, which = 1, stringsAsFactors = FALSE, ...) { .check_pkg_availability("xml2") x <- xml2::as_list(xml2::read_xml(unclass(file)))[[1L]] d <- do.call("rbind", c(lapply(x, unlist))) row.names(d) <- seq_len(nrow(d)) d <- as.data.frame(d, stringsAsFactors = stringsAsFactors) tc2 <- function(x) { out <- utils::type.convert(x, as.is = FALSE) if (is.factor(out)) { x } else { out } } if (!isTRUE(stringsAsFactors)) { d[] <- lapply(d, tc2) } else { d[] <- lapply(d, utils::type.convert) } d } # This is a helper function for .import.rio_html extract_html_row <- function(x, empty_value) { ## Both and are valid for table data, and may be used when ## there is an accented element (e.g. the first row of the table) to_extract <- x[names(x) %in% c("th", "td")] ## Insert a value into cells that eventually will become empty cells (or they ## will be dropped and the table will not be generated). Note that this more ## complex code for finding the length is required because of html like ##
unlist_length <- vapply(lapply(to_extract, unlist), length, integer(1)) to_extract[unlist_length == 0] <- list(empty_value) unlist(to_extract) } #' @export .import.rio_html <- function(file, which = 1, stringsAsFactors = FALSE, ..., empty_value = "") { # find all tables tables <- xml2::xml_find_all(xml2::read_html(unclass(file)), ".//table") if (which > length(tables)) { stop(paste0("Requested table exceeds number of tables found in file (", length(tables), ")!")) } x <- xml2::as_list(tables[[which]]) if ("tbody" %in% names(x)) { # Note that "tbody" may be specified multiple times in a valid html table x <- unlist(x[names(x) %in% "tbody"], recursive = FALSE) } # loop row-wise over the table and then rbind() ## check for table header to use as column names col_names <- NULL if ("th" %in% names(x[[1]])) { col_names <- extract_html_row(x[[1]], empty_value = empty_value) # Drop the first row since column names have already been extracted from it. x <- x[-1] } out <- do.call("rbind", lapply(x, extract_html_row, empty_value = empty_value)) colnames(out) <- if (is.null(col_names)) { paste0("V", seq_len(ncol(out))) } else { col_names } out <- as.data.frame(out, ..., stringsAsFactors = stringsAsFactors) # set row names rownames(out) <- seq_len(nrow(out)) # type.convert() to numeric, etc. out[] <- lapply(out, utils::type.convert, as.is = TRUE) out } #' @export .import.rio_yml <- function(file, which = 1, stringsAsFactors = FALSE, ...) { .check_pkg_availability("yaml") as.data.frame(.docall(yaml::read_yaml, ..., args = list(file = file)), stringsAsFactors = stringsAsFactors) } #' @export .import.rio_eviews <- function(file, which = 1, ...) { .check_pkg_availability("hexView") .docall(hexView::readEViews, ..., args = list(filename = file)) } #' @export .import.rio_clipboard <- function(file = "clipboard", which = 1, header = TRUE, sep = "\t", ...) { .check_pkg_availability("clipr") .docall(clipr::read_clip_tbl, ..., args = list(x = clipr::read_clip(), header = header, sep = sep)) } #' @export .import.rio_pzfx <- function(file, which = 1, ...) { .check_pkg_availability("pzfx") dots <- list(...) if ("path" %in% names(dots)) { dots[["path"]] <- NULL } if ("table" %in% names(dots)) { which <- dots[["table"]] dots[["table"]] <- NULL } .docall(pzfx::read_pzfx, args = c(dots, list(path = file, table = which))) } #' @export .import.rio_parquet <- function(file, which = 1, ...) { .check_pkg_availability("arrow") .docall(arrow::read_parquet, ..., args = list(file = file, as_data_frame = TRUE)) } #' @export .import.rio_qs <- function(file, which = 1, ...) { .check_pkg_availability("qs") .docall(qs::qread, ..., args = list(file = file)) } rio/R/extensions.R0000644000176200001440000000252014500415343013564 0ustar liggesusers.import <- function(file, ...) { UseMethod(".import") } .import.default <- function(file, ...) { fileinfo <- get_info(file) if (is.na(fileinfo$type) || is.na(fileinfo$import_function) || fileinfo$import_function == "") { stop("Format not supported", call. = FALSE) } if (fileinfo$type == "known") { stop(sprintf(gettext("%s format not supported. Consider using the '%s()' function"), fileinfo$format, fileinfo$import_function), call. = FALSE) } if (fileinfo$type == "enhance") { pkg <- stringi::stri_extract_first(fileinfo$import_function, regex = "[a-zA-Z0-9\\.]+") stop(sprintf(gettext("Import support for the %s format is exported by the %s package. Run 'library(%s)' then try again."), fileinfo$format, pkg, pkg), call. = FALSE) } } .export <- function(file, x, ...) { UseMethod(".export") } .export.default <- function(file, x, ...) { fileinfo <- get_info(file) if (is.na(fileinfo$type) || is.na(fileinfo$export_function) || fileinfo$export_function == "") { stop("Format not supported", call. = FALSE) } if (fileinfo$type == "known") { stop(sprintf(gettext("%s format not supported. Consider using the '%s()' function"), fileinfo$format, fileinfo$export_function), call. = FALSE) } } rio/R/standardize_attributes.R0000644000176200001440000000373014047423624016156 0ustar liggesusersstandardize_attributes <- function(dat) { out <- dat a <- attributes(out) if ("variable.labels" %in% names(a)) { names(a)[names(a) == "variable.labels"] <- "var.labels" a$var.labels <- unname(a$var.labels) } # cleanup import attr(out, "var.labels") <- NULL # Stata attr(out, "variable.labels") <- NULL # SPSS attr(out, "formats") <- NULL attr(out, "types") <- NULL attr(out, "label.table") <- NULL for (i in seq_along(out)) { if ("value.labels" %in% names(attributes(out[[i]]))) { attr(out[[i]], "labels") <- attr(out[[i]], "value.labels", exact = TRUE) attr(out[[i]], "value.labels") <- NULL } if (any(grepl("haven_labelled", class(out[[i]])))) { out[[i]] <- unclass(out[[i]]) } if ("var.labels" %in% names(a)) { attr(out[[i]], "label") <- a$var.labels[i] } if (any(grepl("$format", names(a)))) { attr(out[[i]], "format") <- a[[grep("$format", names(a))[1L]]][i] } if ("types" %in% names(a)) { attr(out[[i]], "type") <- a$types[i] } if ("val.labels" %in% names(a) && (a$val.labels[i] != "")) { attr(out[[i]], "labels") <- a$label.table[[a$val.labels[i]]] } } out } restore_labelled <- function(x) { # restore labelled variable classes x[] <- lapply(x, function(v) { if (is.factor(v)) { haven::labelled( x = as.numeric(v), labels = stats::setNames(seq_along(levels(v)), levels(v)), label = attr(v, "label", exact = TRUE) ) } else if (!is.null(attr(v, "labels", exact = TRUE)) || !is.null(attr(v, "label", exact = TRUE))) { haven::labelled( x = v, labels = attr(v, "labels", exact = TRUE), label = attr(v, "label", exact = TRUE) ) } else { v } }) x } rio/NEWS.md0000644000176200001440000005546314502270161012154 0ustar liggesusers# rio 1.0.1 * POTENTIALLY BREAKING: Due to compiling time concerns, roll back the decision to move `arrow` to `Imports`. It is now `Suggests`. `setclass = "arrow"` works if `arrow` is installed. #315 #376 # rio 1.0.0 * Stop loading the entire namespace of a suggested package when it is available #296 * Unexport objects: `.import`, `.export`, `is_file_text`; remove documentation for `arg_reconcile` #321 * Update Examples to make them more realistic #327 * Add support for `qs` #275 h/t David Schoch * Use `arrow` to import / export `feather` #340 * `export_list` can write multiple data frames to a single archive file (e.g. zip, tar) or a directory #346 h/t David Schoch * `get_info` is added #350 * POTENTIALLY BREAKING: `setclass` parameter is now authoritative. Therefore: `import("starwars.csv", data.table = TRUE, setclass = "tibble")` will return a tibble (unlike previous versions where a data.table is returned). The default class is data frame. You can either explicitly use the `setclass` parameter; or set the option: `options(rio.import.class = "data.table")`. h/t David Schoch #336 * Parquet and feather are now formats supported out of the box; Possible to setclass to `arrow` / `arrow_table`; ArrowTabular class can be exported #315 * Add "extension", "labelled" vignettes * Support readODS 2.1.0 features such as reading and writing Flat ODS; export Multiple data frames #358 * POTENTIALLY BREAKING: Use `writexl` instead of `openxlsx`. Option to read xlsx with `openxlsx` (i.e. `import("starwars.xlsx", readxl = FALSE)`) is always `TRUE`. The ability to overwrite an existing sheet in an existing xlsx file is also removed. It is against the design principle of `rio`. * POTENTIALLY BREAKING: The following options are deprecated: `import(fread)`, `import(readr = TRUE)`, `import(haven)`, `import(readxl)` and `export(fwrite)`. import will almost use `data.table`, `haven`, `readxl`, and internal function (for fwf) to import and export data. Currently, those options stay for backward compatibility but will be removed in v2.0.0. #343 h/t David Schoch * POTENTIALLY BREAKING: `...` is handled differently. Underlying functions using "Tidy" convention (e.g. `readxl::read_xlsx()`) can use "Base Convention" (See the new vignette: `remap`). Unused arguments passed to the underlying function as `...` are silently ignored by default. A new option `rio.ignoreunusedargs` is added to control this behavior. #326 * Bug fixes - ... is correctly passed for exporting ODS and feather #318 - POTENTIALLY BREAKING: JSON are exported in UTF-8 by default; solved encoding issues on Windows R < 4.2. This won't affect any modern R installation where UTF-8 is the default. #318 - POTENTIALLY BREAKING: YAML are exported using yaml::write_yaml(). But it can't pass the UTF-8 check on older systems. Disclaimer added. #318 - More check for the `file` argument #301 - `import_list` works with single Excel/HTML/Zip online #294 - Correct XML/HTML escaping #303 - Create directory if it doesn't exist #347 * Declutter - remove the obsolete data.table option #323 - write all documentation blocks in markdown #311 - remove all @importFrom #325 h/t David Schoch - rearrange "Package Philosophy" as a Vignette #320 - Create a single source of truth about all import and export functions #313 - Clarify all concepts: now there is only `format` #351 * New authors - David Schoch @schochastics # rio 0.5.30 * Maintenance release: new maintainer * Mark `.sas7bdat` as deprecated * Change the minimum R version to 3.6 # rio 0.5.29 * fixes for CRAN # rio 0.5.28 * Various fixes to tests, examples, and documentation for CRAN. * Temporarily disabled some tests that failed on Mac M1s. # rio 0.5.27 * Documentation fixes for CRAN. # rio 0.5.26 * Added support for "zsav" format. (#273) # rio 0.5.25 * Modified tests per email request from CRAN. * Added `coerce_character` argument (default FALSE) to `factorize()` to enable coercing character columns to factor. (#278) # rio 0.5.24 * Fix handling of "label" and "labels" attributes when exporting using haven methods (SPSS, Stata, SAS). (#268, h/t Ruben Arslan) * Fix (a different bug?) handling factors by haven::labelled() (#271, Alex Bokov) * HTML import can now handle multiple tbody elements within a single table, a th element in a non-header row, and empty elements in either the header or data. (#260, #263, #264 Bill Denney) # rio 0.5.23 * CSVY support is now provided by `data.table::fread()` and `data.table::fwrite()`, providing significant performance gains. * Added an internal `arg_reconcile()` function to streamline the task of removing/renaming arguments for compatibility with various functions (#245, Alex Bokov) # rio 0.5.22 * Added an `export_list()` function to write a list of data frames to multiple files using a vector of file names or a file pattern. (#207, h/t Bill Denney) * Added an `is_file_text()` function to determine whether a file is in a plain-text format. Optionally narrower subsets of characters can be specified, e.g. ASCII. (#236 Alex Bokov) # rio 0.5.21 * Added support for Apache Arrow (Parquet) files. (#214) * Fix dropping of variable label in `characterize()` and `factorize()`. (#204, h/t David Armstrong) * `import_list()` now returns a `filename` attribute for each data frame in the list (when importing from multiple files), in order to distinguish files with the same base name but different extensions (e.g., `import_list(c("foo.csv", "foo.tsv"))`). (#208, h/t Vimal Rawat) * Import of DBF files now does not convert strings to factors. (#202, h/t @jllipatz) * Implemented `import()` method for .dump R files. (#240) # rio 0.5.20 * Additional pointers were added to indicate how to load .doc, .docx, and .pdf files (#210, h/t Bill Denney) * Ensure that tests only run if the corresponding package is installed. (h/t Bill Denney) * Escape ampersands for html and xml export (#234 Alex Bokov) # rio 0.5.19 * Fix behavior of `export()` to plain text files when `append = TRUE` (#201, h/t Julián Urbano) * `import_list()` now preserve names of Excel sheets, etc. when the 'which' argument is specified. (#162, h/t Danny Parsons) * Modify message and errors when working with unrecognized file formats. (#195, h/t Trevor Davis) * Add support for GraphPad Prism .pzfx files (#205, h/t Bill Denney) # rio 0.5.18 * Adjust `import()`/`export()` for JSON file formats to allow non-data frame objects. Behavior modeled after RDS format. (#199 h/t Nathan Day) # rio 0.5.17 * Fix `the condition has length > 1 and only the first element will be used` warning in `gather_attributes()`. (#196, h/t Ruben Arslan) # rio 0.5.16 * Fix `the condition has length > 1 and only the first element will be used` warning in `standardize_attributes()`. # rio 0.5.15 * Modified some further code to produce compatibility with haven 2.0.0 release. (#188) * Add some additional function suggestions for the ledger package. (#190, h/t Trevor Davis) # rio 0.5.14 * Changes to `gather_attrs()` for haven 2.0.0 release. (#188) * Fixed a bug that generated a superfluous warning in `import()`. * Some style guide changes to code. # rio 0.5.13 * Allow `import()` of objects other than data frames from R-serialized (.rds and .rdata) files. Also, export of such objects to .rds files is supported, as previously intended. (#183, h/t Nicholas Jhirad) * Added (suggests) support for import of EViews files using `hexView::readEViews()`. (#163, h/t Boris Demeshev) # rio 0.5.12 * Add better package specification to `install_formats()` so that it reads from the `Suggests` field of the `DESCRIPTION` file. * Edit header of `README.Rmd` (and thusly `README.md`) to stop complaining about a lack of title field. * Fix typo in `CONTRIBUTING.md` (line said "three arguments", but only listed two). # rio 0.5.11 * Fixed a bug in `import()` wherein matlab files were ignored unless `format` was specified, as well as a related bug that made importing appear to fail for matlab files. (#171) * Fixed a bug in `export()` wherein `format` was ignored. (#99, h/t Sebastian Sauer) * Fixed a bug in the importing of European-style semicolon-separated CSV files. Added a test to ensure correct behavior. (#159, h/t Kenneth Rose) * Updated documentation to reflect recent changes to the xlsx `export()` method. (#156) # rio 0.5.10 * Removed some csvy-related tests, which were failing on CRAN. # rio 0.5.9 * Removed longstanding warnings from the tests of `export()` to fixed-width format. # rio 0.5.8 * Export the `get_ext()` function. (#169) * Fix a bug related to an xml2 bug (#168, h/t Jim Hester) * `import_list()` gains improved file name handling. (#164, h/t Ruaridh Williamson) * Removed the `overwrite` argument from `export()` method for xlsx files. Instead, existing workbooks are always overwritten unless which is specified, in which case only the specified sheet (if it exists) is overwritten. If the file exists but the `which` sheet does not, the data are added as a new sheet to the existing workbook. (#156) # rio 0.5.7 * Import of files with the ambiguous .dat extension, which are typically text-delimited files, are now passed to `data.table::fread()` with a message. Export to the format remains unsupported. (#98, #155) * Added support for export to SAS XPORT format (via `haven::write_xpt()`). (#157) * Switched default import package for SAS XPORT format to `haven::read_xpt()` with a `haven = FALSE` toggle restoring the previous default behavior using `foreign::read.xpt()`. (#157) # rio 0.5.6 * Fixed a bug in `import()` from compressed files wherein the `which` argument did not necessarily return the correct file if >=2 files in the compressed folder. * Tweak handling of `export()` to xlsx workbooks when `which` is specified. (#156) # rio 0.5.5 * Expanded test suite and increased test coverage, fixing a few tests that were failing on certain CRAN builds. # rio 0.5.4 * New functions `characterize()` and `factorize()` provide methods for converting "labelled" variables (e.g., from Stata or SPSS) into character or factor variables using embedded metadata. This can also be useful for exporting a metadata-rich file format into a plain text file. (#153) # rio 0.5.3 * Fixed a bug in writing to .zip and .tar archives related to absolute file paths. * Fixed some small bugs in `import_list()` and added tests for behavior. * Add .bib as known-unsupported format via `bib2df::bib2df()`. * Expanded test coverage. # rio 0.5.3 * Fixed a bug in `.import.rio_xlsx()` when `readxl = FALSE`. (#152, h/t Danny Parsons) * Added a new function `spread_attrs()` that reverses the `gather_attrs()` operation. * Expanded test coverage. # rio 0.5.1 * `export()` now sets variables with a "labels" attribute to **haven**'s "labelled" class. # rio 0.5.0 * CRAN Release. * Restored import of **openxlsx** so that writing to xlsx is supported on install. (#150) # rio 0.4.28 * Improved documentation of mapping between file format support and the packages used for each format. (#151, h/t Patrick Kennedy) * `import_list()` now returns a `NULL` entry for any failed imports, with a warning. (#149) * `import_list()` gains additional arguments `rbind_fill` and `rbind_label` to control rbind-ing behavior. (#149) # rio 0.4.27 * Import to and export from the clipboard now relies on `clipr::read_clip()` and `clipr::write_clip()`, respectively, thus (finally) providing Linux support. (#105, h/t Matthew Lincoln) * Added an `rbind` argument to `import_list()`. (#149) * Added a `setclass` argument to `import_list()`, ala the same in `import()`. * Switched `requireNamespace()` calls to `quietly = TRUE`. # rio 0.4.26 * Further fixes to .csv.gz import/export. (#146, h/t Trevor Davis) # rio 0.4.25 * Remove unecessary **urltools** dependency. * New function `import_list()` returns a list of data frames from a multi-object Excel Workbook, .Rdata file, zip directory, or HTML file. (#126, #129) * `export()` can now write a list of data frames to an Excel (.xlsx) workbook. (#142, h/t Jeremy Johnson) * `export()` can now write a list of data frames to an HTML (.html) file. # rio 0.4.24 * Verbosity of `export(format = "fwf")` now depends on `options("verbose")`. * Fixed various errors, warnings, and messages in fixed-width format tests. * Modified defaults and argument handling in internal function `read_delim()`. * Fixed handling of "data.table", "tibble", and "data.frame" classes in `set_class()`. (#144) # rio 0.4.23 * Moved all non-critical format packages to Suggests, rather than Imports. (#143) * Added support for Matlab formats. (#78, #98) * Added support for fst format. (#138) # rio 0.4.22 * Rearranged README. * Bumped readxl dependency to `>= 0.1.1` (#130, h/t Yongfa Chen) * Pass explicit `excel_format` arguments when using **readxl** functions. (#130) * Google Spreadsheets can now be imported using any of the allowed formats (CSV, TSV, XLSX, ODS). * Added support for writing to ODS files via `readODS::write_ods()`. (#96) # rio 0.4.21 * Handle HTML tables with `` elements. (h/t Mohamed Elgoussi) # rio 0.4.20 * Fixed a big in the `.import.rio_xls()` and `.import.rio_xlsx()` where the `sheet` argument would return an error. # rio 0.4.19 * Fixed a bug in the import of delimited files when `fread = FALSE`. (#133, h/t Christopher Gandrud) # rio 0.4.18 * With new data.table release, export using `fwrite()` is now the default for text-based file formats. # rio 0.4.17 * Fixed a bug in `.import.rio_xls()` wherein the `which` argument was ignored. (h/t Mohamed Elgoussi) # rio 0.4.16 * Added support for importing from multi-table HTML files using the `which` argument. (#126) # rio 0.4.15 * Improved behavior of `import()` and `export()` with respect to unrecognized file types. (#124, #125, h/t Jason Becker) * Added explicit tests of the S3 extension mechanism for `.import()` and `.export()`. * Attempt to recognize compressed but non-archived file formats (e.g., ".csv.gz"). (#123, h/t trevorld) # rio 0.4.14 * Update import and export methods to use new xml2 for XML and HTML export. (#86) # rio 0.4.13 * Fix failing tests related to stricter variable name handling for Stata files in development version of haven. (#113, h/t Hadley Wickham) * Added support for export of .sas7bdat files via haven (#116) * Restored support for import from SPSS portable via haven (#116) * Updated import methods to reflect changed formal argument names in haven. (#116) * Converted to roxygen2 documentation and made NEWS an explicit markdown file. # rio 0.4.12 * rio sets `options(datatable.fread.dec.experiment=FALSE)` during onLoad to address a Unix-specific locale issue. # rio 0.4.11 * Note unsupported NumPy i/o via RcppCNPy. (#112) * Fix import of European-style CSV files (sep = "," and sep2 = ";"). (#106, #107, h/t Stani Stadlmann) # rio 0.4.10 * Changed feather Imports to Suggests to make rio installable on older R versions. (#104) * Noted new RStudio add-in, GREA, that uses rio. (#109) * Migrated CSVY-related code to separate package (https://github.com/leeper/csvy/). (#111) # rio 0.4.9 * Removed unnecessary error in xlsx imports. (#103, h/t Kevin Wright) # rio 0.4.8 * Fixed a bug in the handling of "labelled" class variables imported from haven. (#102, h/t Pierre LaFortune) # rio 0.4.7 * Improved use of the `sep` argument for import of delimited files. (#99, h/t Danny Parsons) * Removed support for import of SPSS Portable (.por) files, given deprecation from haven. (#100) # rio 0.4.5 * Fixed other tests to remove (unimportant) warnings. * Fixed a failing test of file compression that was found in v0.4.3 on some platforms. # rio 0.4.3 * Improved, generalized, tested, and expanded documentation of `which` argument in `import()`. * Expanded test suite and made some small fixes. # rio 0.4.2 * Added support to import and export to `feather` data serialization format. (#88, h/t Jason Becker) # rio 0.4.1 * Fixed behavior of `gather_attrs()` on a data.frame with no attributes to gather. (#94) * Removed unrecognized file format error for import from compressed files. (#93) # rio 0.4.0 * CRAN Release. # rio 0.3.19 * Added a `gather_attrs()` function that moves variable-level attributes to the data.frame level. (#80) * Added preliminary support for import from HTML tables (#86) # rio 0.3.18 * Added support for export to HTML tables. (#86) # rio 0.3.17 * Fixed a bug in import from remote URLs with incorrect file extensions. # rio 0.3.16 * Added support for import from fixed-width format files via `readr::read_fwf()` with a specified `widths` argument. This may enable faster import of these types of files and provides a base-like interface for working with readr. (#48) # rio 0.3.15 * Added support for import from and export to yaml. (#83) * Fixed a bug when reading from an uncommented CSVY yaml header that contained single-line comments. (#84, h/t Tom Aldenberg) # rio 0.3.14 * Diagnostic messages were cleaned up to facilitate translation. (#57) # rio 0.3.12 * `.import()` and `.export()` are now exported S3 generics and documentation has been added to describe how to write rio extensions for new file types. An example of this functionality is shown in the new suggested "rio.db" package. # rio 0.3.11 * `import()` now uses xml2 to read XML structures and `export()` uses a custom method for writing to XML, thereby negating dependency on the XML package. (#67) * Enhancements were made to import and export of CSVY to store attribute metadata as variable-level attributes (like imports from binary file formats). * `import()` gains a `which` argument that is used to select which file to return from within a compressed tar or zip archive. * Export to tar now tries to correct for bugs in `tar()` that are being fixed in base R via [PR#16716](https://bugs.r-project.org/show_bug.cgi?id=16716). # rio 0.3.10 * Fixed a bug in `import()` (introduced in #62, 7a7480e5) that prevented import from clipboard. (h/t Kevin Wright) * `export()` returns a character string. (#82) # rio 0.3.9 * The use of `import()` for SAS, Stata, and SPSS files has been streamlined. Regardless of whether the `haven = TRUE` argument is used, the data.frame returned by `import()` should now be (nearly) identical, with all attributes stored at the variable rather than data.frame level. This is a non-backwards compatible change. (#80) # rio 0.3.8 * Fixed error in export to CSVY with a commented yaml header. (#81, h/t Andrew MacDonald) # rio 0.3.7 * `export()` now allows automatic file compression as tar, gzip, or zip using the `file` argument (e.g., `export(iris, "iris.csv.zip")`). # rio 0.3.6 * Expanded verbosity of `export()` for fixed-width format files and added a commented header containing column class and width information. * Exporting factors to fixed-width format now saves those values as integer rather than numeric. * Expanded test suite and separated tests into format-specific files. (#51) # rio 0.3.5 * Export of CSVY files now includes commenting the yaml header by default. Import of CSVY accommodates this automatically. (#74) # rio 0.3.3 * Export of CSVY files and metadata now supported by `export()`. (#73) * Import of CSVY files now stores dataset-level metadata in attributes of the output data.frame. (#73, h/t Tom Aldenberg) * When rio receives an unrecognized file format, it now issues a message. The new internal `.import.default()` and `.export.default()` then produce an error. This enables add-on packages to support additional formats through new s3 methods of the form `.import.rio_EXTENSION()` and `.export.rio_EXTENSION()`. # rio 0.3.2 * Use S3 dispatch internally to call new (unexported) `.import()` and `.export()` methods. (#42, h/t Jason Becker) # rio 0.3.0 * Release to CRAN. * Set a default numerical precision (of 2 decimal places) for export to fixed-width format. # rio 0.2.13 * Import stats package for `na.omit()`. # rio 0.2.11 * Added support for direct import from Google Sheets. (#60, #63, h/t Chung-hong Chan) # rio 0.2.7 * Refactored remote file retrieval into separate (non-exported) function used by `import()`. (#62) * Added test sutie to test file conversion. * Expanded test suite to include test of all export formats. # rio 0.2.6 * Cleaned up NAMESPACE file. # rio 0.2.5 * If file format for a remote file cannot be identified from the supplied URL or the final URL reported by `curl::curl_fetch_memory()`, the HTTP headers are checked for a filename in the Content-Disposition header. (#36) * Removed longurl dependency. This is no longer needed because we can identify formats using curl's url argument. * Fixed a bug related to importing European-style ("csv2") format files. (#44) * Updated CSVY import to embed variable-level metadata. (#52) * Use `urltools::url_parse()` to extract file extensions from complex URLs (e.g., those with query arguments). (#56) * Fixed NAMESPACE notes for base packages. (#58) # rio 0.2.4 * Modified behavior so that files imported using haven now store variable metadata at the data.frame level by default (unlike the default behavior in haven, which can cause problems). (#37, h/t Ista Zahn) * Added support for importing CSVY (http://csvy.org/) formatted files. (#52) * Added import dependency on data.table 1.9.5. (#39) # rio 0.2.2 * Uses the longurl package to expand shortened URLs so that their file type can be easily determined. # rio 0.2.1 * Improved support for importing from compressed directories, especially web-based compressed directories. (#38) * Add import dependency on curl >= 0.6 to facilitate content type parsing and format inference from URL redirects. (#36) * Add bit64 to `Suggests` to remove an `import` warning. # rio 0.2 * `import` always returns a data.frame, unless `setclass` is specified. (#22) * Added support for import from legacy Excel (.xls) files `readxl::read_excel`, making its use optional. (#19) * Added support for import from and export to the system clipboard on Windows and Mac OS. * Added support for export to simple XML documents. (#12) * Added support for import from simple XML documents via `XML::xmlToDataFrame`. (#12) * Added support for import from ODS spreadsheet formats. (#12, h/t Chung-hong Chan) * Use `data.table::fread` by default for reading delimited files. (#3) * Added support for import and export of `dput` and `dget` objects. (#10) * Added support for reading from compressed archives (.zip and .tar). (#7) * Added support for writing to fixed-width format. (#8) * Set `stringsAsFactors = FALSE` as default for reading tabular data. (#4) * Added support for HTTPS imports. (#1, h/t Christopher Gandrud) * Added support for automatic file naming in `export` based on object name and file format. (#5) * Exposed `convert` function. * Added vignette, knitr-generated README.md, and updated documentation. (#2) * Added some non-exported functions to simplify argument passing and streamline package API. (#6) * Separated `import`, `export`, `convert`, and utilities into separate source code files. * Expanded the set of supported file types/extensions, switched SPSS, SAS, and Stata formats to **haven**, making its use optional. # rio 0.1.2 * Updated documentation and fixed a bug in csv import without header. # rio 0.1.1 * Initial release rio/MD50000644000176200001440000001525214502301742011356 0ustar liggesusers52dd2135d3a65fc47571b5bf02af2fda *DESCRIPTION 8620a402d96d51752db18d32efeccca9 *NAMESPACE 007ac6ea046db5e0e04232e721ef45f6 *NEWS.md 57348ed683ea9ae7d0074d1148734984 *R/characterize.R 9e468263ae985fff236779d9ac527349 *R/compression.R 807ddc7d46c576546e3a1e74d634153a *R/convert.R 4ed76bec4c03c9ef218970aec509d196 *R/convert_google_url.R b5d359b8a763deb0c5a2df13cdbeff54 *R/export.R c8b2823f7d78263212092283b7162e8d *R/export_list.R ec0631fc86468c1e51dcf805969afd5a *R/export_methods.R 97a8ad884611baaf0a7c99dccb774e6c *R/extensions.R 1e9b157ef13f4b54be80a6d0dc19e662 *R/fwf2.R 1f8a8d99f0065ce6838ee9da5a296997 *R/gather_attrs.R 6562a6d961d08b6d5bd9d718c3739415 *R/import.R 2e587ae64754f7310ad1afd57171f875 *R/import_list.R 1a74c7d44aaa43bb477c8612c89e73f8 *R/import_methods.R 6aa35f37902e4a6e41644eb1c13c0c0d *R/onLoad.R 290f8ec0f0751950d1b7f69e1a069c30 *R/remote_to_local.R a0039ac1f1b4a1756b5fbd1f17aaf123 *R/rio.R 7f3375a79b38a744a74efbc05d0b36bd *R/set_class.R dea60da2d4b126a492f3b687e2855429 *R/standardize_attributes.R 08f55ef8c61e6fc1d7ecc37a3f20d5fa *R/suggestions.R 61c447cd9333226c5334df8e49a23abc *R/sysdata.rda 34032b91957ab3cd796c70b95bc1ceb4 *R/utils.R c9bcb213f4245c1825b761a096eccf5d *README.md 5f0e710a2fc076f245dae937ba24f38f *build/vignette.rds 10d45832d34b09559c23c29362cad423 *inst/CITATION 5c30adebcb89825549d5609439609123 *inst/doc/extension.R b64f6b55503c515566fe4b04f0970506 *inst/doc/extension.html f12bff071ab3f2dbac493065848f98d4 *inst/doc/labelled.R d0a1d2b0c4d687d3a26debe12bcb6288 *inst/doc/labelled.html 025ab9954487385475120a43d87d1939 *inst/doc/philosophy.html d116bfee8d3ecab767af9a97f11cc9d1 *inst/doc/remap.R 6ea479b8ecbbc3786bad50a1dcb095f8 *inst/doc/remap.html 7097b4171107d7905a08fba7f3f2a474 *inst/doc/rio.R 3617ad3d59a4b3c3e66c873d09b52b60 *inst/doc/rio.html 83ac65fcc39b019e543625a644ef7c0d *man/characterize.Rd 2a8458a6c3e87a9730f950a6b515d8bd *man/convert.Rd 0ff26ce0a51199a139d8ae140306ca55 *man/export.Rd 6f6502b0216c9a460de2ef585e387b40 *man/export_list.Rd 304a97e1daed89f334a63a8bd3b01e92 *man/figures/logo.png 61984e9c0ba9be0c16c78fb7ddcb2acf *man/figures/logo.svg b489e27261df285a9b745c2a9e237dd7 *man/gather_attrs.Rd 7a68d23fb71d862762c89f8664e12d82 *man/get_info.Rd 103977b3db050c483a4f691d31ade39a *man/import.Rd 8b0f6fb2bdf0fe0d50b538b223368896 *man/import_list.Rd eca73c5794e8709a745a8240da096236 *man/install_formats.Rd c6c16fa869b6ac28effa638567308e07 *man/rio.Rd 02b321d1a6316f1fa55516db1b98beab *po/R-rio.pot c821c83f4f2653452a2b879a651587f6 *tests/testdata/br-in-header.html 79d5fe2395aced85b680233cd7754bcb *tests/testdata/br-in-td.html b80fc98b7502d9911f80b1fd3045f986 *tests/testdata/example.csvy 408c5b85e5327e84302fe436e90c412e *tests/testdata/iris.xls d939406722129d3bed0bb2c7f9ffd715 *tests/testdata/mtcars.ods da76d4babe6ce26b1390804777acc096 *tests/testdata/noheader.csv 058b2178e4144577223a43218d0bc418 *tests/testdata/th-as-row-element.html 17a3650e8214de3d8fae36afb88e0a00 *tests/testdata/two-tbody.html a36ec1e977cdbdf07b230e5a0e0a949b *tests/testdata/twotables.html dc67e448382de1d8b4c3d9084d2545a6 *tests/testthat.R 150ef1b618d25470eca8e464b065fd56 *tests/testthat/test_characterize.R 67383710c443c5debca7062cd0c801f9 *tests/testthat/test_check_file.R c3f075a0300d348fe16f0493e8932566 *tests/testthat/test_compress.R f6ea29ffccb370d62ead35cdd819d591 *tests/testthat/test_convert.R 49af6144c1cd9b739d28dd49b49abcca *tests/testthat/test_create_outfiles.R f4d3359036c9a5fbc76131d707f8cd70 *tests/testthat/test_errors.R 8872fc956faf39a9ad34fb20e2946e2a *tests/testthat/test_export_corner_cases.R facd92c32c2e807a6b76f99234ef9664 *tests/testthat/test_export_list.R 2618c034174975b747867087af049c06 *tests/testthat/test_extensions.R babf164a4f2cc6e12d6cb1b7cfd81033 *tests/testthat/test_format_R.R 5700f8c7db661200c5540bb17278b184 *tests/testthat/test_format_arff.R 7b29cb1531a578ccbd4500c40a92be90 *tests/testthat/test_format_csv.R 5054cd3adb1d339b95dd3612536c3bdd *tests/testthat/test_format_csv_gz.R 73794f5e8f5c1eda9fa538978c1248bb *tests/testthat/test_format_csvy.R ed232c90bffd6a4729755deb7c0a64e9 *tests/testthat/test_format_dbf.R 61d45f88351bcd5910500a8d3266db18 *tests/testthat/test_format_dif.R 4da73b10401e3b77ab4f80f9a4c6f3cd *tests/testthat/test_format_dta.R 82d24ed71478d973a89f90997640a83d *tests/testthat/test_format_eviews.R 9fda84adf7d8ce3bcf61d086d619559b *tests/testthat/test_format_external_packages.R d1eec67b66dfddf1d48215a7e95616aa *tests/testthat/test_format_feather.R 3bcc3f1942e468cb3f86ba21a03027e4 *tests/testthat/test_format_fortran.R 30ce81ecc355eca75966a5ef495dc67c *tests/testthat/test_format_fst.R b5b3a334837f04735b04c1b8aac8fffc *tests/testthat/test_format_fwf.R c705ca7664d04377b5ea5095911dfdc4 *tests/testthat/test_format_html.R d8faf8bb450c9c759cea520bd315f965 *tests/testthat/test_format_json.R 6f3a3ea3392d126e0b2e086e75783ba7 *tests/testthat/test_format_matlab.R bd804021ab2f99a518aebb7f649ed6fa *tests/testthat/test_format_mtp.R e81bc031b08f9cc5f611556f15af9253 *tests/testthat/test_format_ods.R 321b7ceeb26b9ed0c4022b6d7bf9344b *tests/testthat/test_format_parquet.R 8594d41213946c094def1c8edae56055 *tests/testthat/test_format_psv.R c8cef9129417db6e2f17495b4962146d *tests/testthat/test_format_pzfx.R b99f815ff9b6f71e79efc54cd1a62e70 *tests/testthat/test_format_qs.R 99def0c0d7100784bce927330a69ea7f *tests/testthat/test_format_rdata.R 25f00787f3310ab5ae54e7b06366400e *tests/testthat/test_format_rds.R 0bc0904ea7a96be50dbfbe986da00b79 *tests/testthat/test_format_rec.R a33df65e1ba1551eff318d3d08328046 *tests/testthat/test_format_sas.R 97193971ceea6a34ebd52c9958b94a6a *tests/testthat/test_format_sav.R 4f8d69f8854bbe17e644925ad480f382 *tests/testthat/test_format_syd.R 4015b4afd9e764144a33b2945c3f8f63 *tests/testthat/test_format_tsv.R d4fa6346b5f071114642f65badb7bd14 *tests/testthat/test_format_xls.R 9d116332206085abc534467dfc9e57f8 *tests/testthat/test_format_xml.R 8c4c93e2190db6285e9651fb1c477d48 *tests/testthat/test_format_yml.R e272f29f87dbe90eee1dc17c4cb9955b *tests/testthat/test_gather_attrs.R 404e638bb97dc37e7c46a327e24faa3d *tests/testthat/test_guess.R 724139955415eb0c3dc5d56c1d8b2d8d *tests/testthat/test_identical.R 73d0eac66a741876aac9d92312ea0c35 *tests/testthat/test_import_list.R ba57b665262db96fc3eebbf8508b9f42 *tests/testthat/test_install_formats.R 660a35e980c7fa026f5443c4985ca582 *tests/testthat/test_mapping.R 1b706f007b344f282c9fc8902ad75315 *tests/testthat/test_matrix.R c66d5e82390e631f457d76ca98cbf5c2 *tests/testthat/test_remote.R dbc1ebdf4ae3ed68fee6898c0900dc4a *tests/testthat/test_set_class.R de6ca8d3c9e38a95202c14292ac751d3 *vignettes/extension.Rmd 8edce779bf5ec09051660d36fb752f4f *vignettes/labelled.Rmd e4b763cf530cfddf61dab5960bfa0701 *vignettes/philosophy.Rmd 90548ab54f3da7b62b48da133ceac2cb *vignettes/remap.Rmd 135bede0a10ba3950b95af3b88bb6a28 *vignettes/rio.Rmd rio/inst/0000755000176200001440000000000014502270453012022 5ustar liggesusersrio/inst/doc/0000755000176200001440000000000014502270453012567 5ustar liggesusersrio/inst/doc/remap.R0000644000176200001440000000213414502270452014015 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----map1--------------------------------------------------------------------- library(rio) export(list("mtcars" = mtcars, "iris" = iris), "example.xlsx") import("example.xlsx", which = "mtcars") ## ----map2--------------------------------------------------------------------- import("example.xlsx", sheet = "mtcars") ## ----map3--------------------------------------------------------------------- ## n_max is an argument of readxl::read_xlsx import("example.xlsx", sheet = "iris", n_max = 10) ## ----map4--------------------------------------------------------------------- import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") ## ----map5, error = TRUE, echo = FALSE----------------------------------------- R.utils::withOptions({ import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") }, rio.ignoreunusedargs = FALSE) ## ----echo = FALSE, results = 'hide'------------------------------------------- unlink("example.xlsx") rio/inst/doc/extension.R0000644000176200001440000000035614502270451014730 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(rio) rio/inst/doc/philosophy.html0000644000176200001440000003546614502270452015670 0ustar liggesusers Package Philosophy

Package Philosophy

The core advantage of rio is that it makes assumptions that the user is probably willing to make. Eight of these are important:

  1. rio uses the file extension of a file name to determine what kind of file it is. This is the same logic used by Windows OS, for example, in determining what application is associated with a given file type. By removing the need to manually match a file type (which a beginner may not recognize) to a particular import or export function, rio allows almost all common data formats to be read with the same function. And if a file extension is incorrect, users can force a particular import method by specifying the format argument.

  2. rio uses data.table::fread() for text-delimited files to automatically determine the file format regardless of the extension. So, a CSV that is actually tab-separated will still be correctly imported. It’s also crazy fast.

  3. rio, wherever possible, does not import character strings as factors.

  4. rio supports web-based imports natively, including from SSL (HTTPS) URLs, from shortened URLs, from URLs that lack proper extensions, and from (public) Google Documents Spreadsheets.

  5. rio imports from from single-file .zip and .tar archives automatically, without the need to explicitly decompress them. Export to compressed directories is also supported.

  6. rio wraps a variety of faster, more stream-lined I/O packages than those provided by base R or the foreign package. It uses data.table for delimited formats, haven for SAS, Stata, and SPSS files, smarter and faster fixed-width file import and export routines, and readxl and openxlsx for reading and writing Excel workbooks.

  7. rio stores metadata from rich file formats (SPSS, Stata, etc.) in variable-level attributes in a consistent form regardless of file type or underlying import function. These attributes are identified as:

    • label: a description of variable
    • labels: a vector mapping numeric values to character strings those values represent
    • format: a character string describing the variable storage type in the original file

    The gather_attrs() function makes it easy to move variable-level attributes to the data frame level (and spread_attrs() reverses that gathering process). These can be useful, especially, during file conversion to more easily modify attributes that are handled differently across file formats. As an example, the following idiom can be used to trim SPSS value labels to the 32-character maximum allowed by Stata:

    dat <- gather_attrs(rio::import("data.sav"))
    attr(dat, "labels") <- lapply(attributes(dat)$labels, function(x) {
        if (!is.null(x)) {
            names(x) <- substring(names(x), 1, 32)
        }
        x
    })
    export(spread_attrs(dat), "data.dta")

    In addition, two functions (added in v0.5.5) provide easy ways to create character and factor variables from these “labels” attributes. characterize() converts a single variable or all variables in a data frame that have “labels” attributes into character vectors based on the mapping of values to value labels. factorize() does the same but returns factor variables. This can be especially helpful for converting these rich file formats into open formats (e.g., export(characterize(import("file.dta")), "file.csv").

  8. rio imports and exports files based on an internal S3 class infrastructure. This means that other packages can contain extensions to rio by registering S3 methods. These methods should take the form .import.rio_X() and .export.rio_X(), where X is the file extension of a file type. An example is provided in the rio.db package.

rio/inst/doc/rio.html0000644000176200001440000343525114502270453014263 0ustar liggesusers Import, Export, and Convert Data Files

Import, Export, and Convert Data Files

The idea behind rio is to simplify the process of importing data into R and exporting data from R. This process is, probably unnecessarily, extremely complex for beginning R users. Indeed, R supplies an entire manual describing the process of data import/export. And, despite all of that text, most of the packages described are (to varying degrees) out-of-date. Faster, simpler, packages with fewer dependencies have been created for many of the file types described in that document. rio aims to unify data I/O (importing and exporting) into two simple functions: import() and export() so that beginners (and experienced R users) never have to think twice (or even once) about the best way to read and write R data.

The core advantage of rio is that it makes assumptions that the user is probably willing to make. Specifically, rio uses the file extension of a file name to determine what kind of file it is. This is the same logic used by Windows OS, for example, in determining what application is associated with a given file type. By taking away the need to manually match a file type (which a beginner may not recognize) to a particular import or export function, rio allows almost all common data formats to be read with the same function.

By making import and export easy, it’s an obvious next step to also use R as a simple data conversion utility. Transferring data files between various proprietary formats is always a pain and often expensive. The convert function therefore combines import and export to easily convert between file formats (thus providing a FOSS replacement for programs like Stat/Transfer or Sledgehammer).

Supported file formats

rio supports a variety of different file formats for import and export. To keep the package slim, all non-essential formats are supported via “Suggests” packages, which are not installed (or loaded) by default. To ensure rio is fully functional, install these packages the first time you use rio via:

install_formats()

The full list of supported formats is below:

Name Extensions / “format” Import Package Export Package Type Note
Archive files (handled by tar) bzip2 / xz / tar utils utils Default
Gzip files gz / gzip base base Default
Zip files zip utils utils Default
CSVY (CSV + YAML metadata header) csvy data.table data.table Default
Comma-separated data csv data.table data.table Default
Comma-separated data (European) csv2 data.table data.table Default
Data Interchange Format dif utils Default
Epiinfo epiinfo / rec foreign Default
Excel excel / xlsx readxl writexl Default
Excel (Legacy) xls readxl Default
Fixed-width format data fwf utils utils Default
Fortran data fortran utils Default No recognized extension
Google Sheets googlesheets data.table Default As comma-separated data
Minitab minitab / mtp foreign Default
Pipe-separated data psv data.table data.table Default
R syntax r base base Default
SAS sas / sas7bdat haven haven Default Export is deprecated
SAS XPORT xport / xpt haven haven Default
SPSS sav / spss haven haven Default
SPSS (compressed) zsav haven haven Default
SPSS Portable por haven Default
Saved R objects rda / rdata base base Default
Serialized R objects rds base base Default
Stata dta / stata haven haven Default
Systat syd / systat foreign Default
Tab-separated data / tsv / txt data.table data.table Default
Text Representations of R Objects dump base base Default
Weka Attribute-Relation File Format arff / weka foreign foreign Default
XBASE database files dbf foreign foreign Default
Apache Arrow (Parquet) parquet arrow arrow Suggest
Clipboard clipboard clipr clipr Suggest default is tsv
EViews eviews / wf1 hexView Suggest
Fast Storage fst fst fst Suggest
Feather R/Python interchange format feather arrow arrow Suggest
Graphpad Prism pzfx pzfx pzfx Suggest
HTML Tables htm / html xml2 xml2 Suggest
JSON json jsonlite jsonlite Suggest
Matlab mat / matlab rmatio rmatio Suggest
OpenDocument Spreadsheet ods readODS readODS Suggest
OpenDocument Spreadsheet (Flat) fods readODS readODS Suggest
Serialized R objects (Quick) qs qs qs Suggest
Shallow XML documents xml xml2 xml2 Suggest
YAML yaml / yml yaml yaml Suggest

Additionally, any format that is not supported by rio but that has a known R implementation will produce an informative error message pointing to a package and import or export function. Unrecognized formats will yield a simple “Unrecognized file format” error.

Data Import

rio allows you to import files in almost any format using one, typically single-argument, function. import() infers the file format from the file’s extension and calls the appropriate data import function for you, returning a simple data.frame. This works for any for the formats listed above.

library("rio")

x <- import("mtcars.csv")
y <- import("mtcars.rds")
z <- import("mtcars.dta")

# confirm identical
all.equal(x, y, check.attributes = FALSE)
## [1] TRUE
all.equal(x, z, check.attributes = FALSE)
## [1] TRUE

If for some reason a file does not have an extension, or has a file extension that does not match its actual type, you can manually specify a file format to override the format inference step. For example, we can read in a CSV file that does not have a file extension by specifying csv:

head(import("mtcars_noext", format = "csv"))
##    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Importing Data Lists

Sometimes you may have multiple data files that you want to import. import() only ever returns a single data frame, but import_list() can be used to import a vector of file names into R. This works even if the files are different formats:

str(import_list(dir()), 1)

Similarly, some single-file formats (e.g. Excel Workbooks, Zip directories, HTML files, etc.) can contain multiple data sets. Because import() is type safe, always returning a data frame, importing from these formats requires specifying a which argument to import() to dictate which data set (worksheet, file, table, etc.) to import (the default being which = 1). But import_list() can be used to import all (or only a specified subset, again via which) of data objects from these types of files.

Data Export

The export capabilities of rio are somewhat more limited than the import capabilities, given the availability of different functions in various R packages and because import functions are often written to make use of data from other applications and it never seems to be a development priority to have functions to export to the formats used by other applications. That said, rio currently supports the following formats:

library("rio")

export(mtcars, "mtcars.csv")
export(mtcars, "mtcars.rds")
export(mtcars, "mtcars.dta")

It is also easy to use export() as part of an R pipeline (from magrittr or dplyr). For example, the following code uses export() to save the results of a simple data transformation:

library("magrittr")
mtcars %>%
  subset(hp > 100) %>%
  aggregate(. ~ cyl + am, data = ., FUN = mean) %>%
  export(file = "mtcars2.dta")

Some file formats (e.g., Excel workbooks, Rdata files) can support multiple data objects in a single file. export() natively supports output of multiple objects to these types of files:

# export to sheets of an Excel workbook
export(list(mtcars = mtcars, iris = iris), "multi.xlsx")
# export to an .Rdata file
## as a named list
export(list(mtcars = mtcars, iris = iris), "multi.rdata")

## as a character vector
export(c("mtcars", "iris"), "multi.rdata")

It is also possible to use the new (as of v0.6.0) function export_list() to write a list of data frames to multiple files using either a vector of file names or a file pattern:

export_list(list(mtcars = mtcars, iris = iris), "%s.tsv")

File Conversion

The convert() function links import() and export() by constructing a dataframe from the imported file and immediately writing it back to disk. convert() invisibly returns the file name of the exported file, so that it can be used to programmatically access the new file.

Because convert() is just a thin wrapper for import() and export(), it is very easy to use. For example, we can convert

# create file to convert
export(mtcars, "mtcars.dta")

# convert Stata to SPSS
convert("mtcars.dta", "mtcars.sav")

convert() also accepts lists of arguments for controlling import (in_opts) and export (out_opts). This can be useful for passing additional arguments to import or export methods. This could be useful, for example, for reading in a fixed-width format file and converting it to a comma-separated values file:

# create an ambiguous file
fwf <- tempfile(fileext = ".fwf")
cat(file = fwf, "123456", "987654", sep = "\n")

# see two ways to read in the file
identical(import(fwf, widths = c(1, 2, 3)), import(fwf, widths = c(1, -2, 3)))
## [1] FALSE
# convert to CSV
convert(fwf, "fwf.csv", in_opts = list(widths = c(1, 2, 3)))
import("fwf.csv") # check conversion
##   V1 V2  V3
## 1  1 23 456
## 2  9 87 654

With metadata-rich file formats (e.g., Stata, SPSS, SAS), it can also be useful to pass imported data through characterize() or factorize() when converting to an open, text-delimited format: characterize() converts a single variable or all variables in a data frame that have “labels” attributes into character vectors based on the mapping of values to value labels (e.g., export(characterize(import("file.dta")), "file.csv")). An alternative approach is exporting to CSVY format, which records metadata in a YAML-formatted header at the beginning of a CSV file.

It is also possible to use rio on the command-line by calling Rscript with the -e (expression) argument. For example, to convert a file from Stata (.dta) to comma-separated values (.csv), simply do the following:

Rscript -e "rio::convert('mtcars.dta', 'mtcars.csv')"
rio/inst/doc/remap.html0000644000176200001440000006523214502270452014570 0ustar liggesusers Remapping and Ellipsis

Remapping and Ellipsis

Remapping

There are two conventions of arguments among the underlying functions used by rio. Let’s call them Base Convention and “Tidy” Convention.

Convention file location selection of sheet header examples
Base file which header clipr::read_clip_tbl
“Tidy” path sheet col_names readxl::read_xlsx, readxl::read_xls, readODS::read_ods

rio can map Base Convention into “Tidy” Convention (but not vice versa).

library(rio)
export(list("mtcars" = mtcars, "iris" = iris), "example.xlsx")
import("example.xlsx", which = "mtcars")
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

But you can still use the “Tidy” Convention, if the underlying function supports it.

import("example.xlsx", sheet = "mtcars")
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Ellipsis or “dot dot dot”

Additional parameters are usually passed to the underlying function as ellipsis (...).

## n_max is an argument of readxl::read_xlsx
import("example.xlsx", sheet = "iris", n_max = 10)
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1           5.1         3.5          1.4         0.2  setosa
#> 2           4.9         3.0          1.4         0.2  setosa
#> 3           4.7         3.2          1.3         0.2  setosa
#> 4           4.6         3.1          1.5         0.2  setosa
#> 5           5.0         3.6          1.4         0.2  setosa
#> 6           5.4         3.9          1.7         0.4  setosa
#> 7           4.6         3.4          1.4         0.3  setosa
#> 8           5.0         3.4          1.5         0.2  setosa
#> 9           4.4         2.9          1.4         0.2  setosa
#> 10          4.9         3.1          1.5         0.1  setosa

Parameters that the underlying function do not recognize are silently ignored by default.

import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple")
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1           5.1         3.5          1.4         0.2  setosa
#> 2           4.9         3.0          1.4         0.2  setosa
#> 3           4.7         3.2          1.3         0.2  setosa
#> 4           4.6         3.1          1.5         0.2  setosa
#> 5           5.0         3.6          1.4         0.2  setosa
#> 6           5.4         3.9          1.7         0.4  setosa
#> 7           4.6         3.4          1.4         0.3  setosa
#> 8           5.0         3.4          1.5         0.2  setosa
#> 9           4.4         2.9          1.4         0.2  setosa
#> 10          4.9         3.1          1.5         0.1  setosa

If you don’t like this behavior, please change the option rio.ignoreunusedargs to FALSE, i.e. option(rio.ignoreunusedargs = FALSE).

options(rio.ignoreunusedargs = FALSE)
import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple")
#> Error in (function (path, sheet = NULL, range = NULL, col_names = TRUE, : unused argument (pizza = "pineapple")
rio/inst/doc/labelled.html0000644000176200001440000004241214502270452015223 0ustar liggesusers Working with labelled data

Working with labelled data

library(rio)
library(haven)

Formats SAS, SPSS, and Stata use haven as import and export functions. And these formats can have the so-called labelled data. For more information, please read vignette("semantics", "haven"). Here, we provide a quick guide on how to work with labelled data using rio.

You can use haven::labelled() to create labelled data.

gender <- haven::labelled(
                     c("M", "F", "F", "F", "M"),
                     c(Male = "M", Female = "F"))

Or directly using attrs

rating <- sample(1:5)
attr(rating, "labels") <-  c(c(Good = 1, Bad = 5))
mydata <- data.frame(gender, rating)

Round trip: The data labels are retained. But they are at the variable level.

export(mydata, "mydata.sav")
restored_data <- rio::import("mydata.sav")
str(restored_data)
#> 'data.frame':    5 obs. of  2 variables:
#>  $ gender: chr  "M" "F" "F" "F" ...
#>   ..- attr(*, "format.spss")= chr "A1"
#>   ..- attr(*, "labels")= Named chr [1:2] "M" "F"
#>   .. ..- attr(*, "names")= chr [1:2] "Male" "Female"
#>  $ rating: num  2 3 5 4 1
#>   ..- attr(*, "format.spss")= chr "F8.0"
#>   ..- attr(*, "labels")= Named num [1:2] 1 5
#>   .. ..- attr(*, "names")= chr [1:2] "Good" "Bad"

rio::gather_attrs() converts attributes to the data.frame level

g <- rio::gather_attrs(restored_data)
str(g)
#> 'data.frame':    5 obs. of  2 variables:
#>  $ gender: chr  "M" "F" "F" "F" ...
#>   ..- attr(*, "labels")= Named chr [1:2] "M" "F"
#>   .. ..- attr(*, "names")= chr [1:2] "Male" "Female"
#>  $ rating: num  2 3 5 4 1
#>   ..- attr(*, "labels")= Named num [1:2] 1 5
#>   .. ..- attr(*, "names")= chr [1:2] "Good" "Bad"
#>  - attr(*, "format.spss")=List of 2
#>   ..$ gender: chr "A1"
#>   ..$ rating: chr "F8.0"
#>  - attr(*, "labels")=List of 2
#>   ..$ gender: Named chr [1:2] "M" "F"
#>   .. ..- attr(*, "names")= chr [1:2] "Male" "Female"
#>   ..$ rating: Named num [1:2] 1 5
#>   .. ..- attr(*, "names")= chr [1:2] "Good" "Bad"
attr(g, "labels")
#> $gender
#>   Male Female 
#>    "M"    "F" 
#> 
#> $rating
#> Good  Bad 
#>    1    5
rio/inst/doc/labelled.R0000644000176200001440000000220414502270452014453 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----------------------------------------------------------------------------- library(rio) library(haven) ## ----------------------------------------------------------------------------- gender <- haven::labelled( c("M", "F", "F", "F", "M"), c(Male = "M", Female = "F")) ## ----------------------------------------------------------------------------- rating <- sample(1:5) attr(rating, "labels") <- c(c(Good = 1, Bad = 5)) ## ----------------------------------------------------------------------------- mydata <- data.frame(gender, rating) ## ----------------------------------------------------------------------------- export(mydata, "mydata.sav") restored_data <- rio::import("mydata.sav") str(restored_data) ## ----------------------------------------------------------------------------- g <- rio::gather_attrs(restored_data) str(g) attr(g, "labels") ## ----include = FALSE---------------------------------------------------------- unlink("mydata.sav") rio/inst/doc/rio.R0000644000176200001440000001017014502270453013502 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- suppressPackageStartupMessages(library(data.table)) ## ----featuretable, echo = FALSE----------------------------------------------- rf <- data.table(rio:::rio_formats)[!input %in% c(",", ";", "|", "\\t") & type %in% c("import", "suggest", "archive"),] short_rf <- rf[, paste(input, collapse = " / "), by = format_name] type_rf <- unique(rf[,c("format_name", "type", "import_function", "export_function", "note")]) feature_table <- short_rf[type_rf, on = .(format_name)] colnames(feature_table)[2] <- "signature" setorder(feature_table, "type", "format_name") feature_table$import_function <- stringi::stri_extract_first(feature_table$import_function, regex = "[a-zA-Z0-9\\.]+") feature_table$import_function[is.na(feature_table$import_function)] <- "" feature_table$export_function <- stringi::stri_extract_first(feature_table$export_function, regex = "[a-zA-Z0-9\\.]+") feature_table$export_function[is.na(feature_table$export_function)] <- "" feature_table$type <- ifelse(feature_table$type %in% c("suggest"), "Suggest", "Default") feature_table <- feature_table[,c("format_name", "signature", "import_function", "export_function", "type", "note")] colnames(feature_table) <- c("Name", "Extensions / \"format\"", "Import Package", "Export Package", "Type", "Note") knitr::kable(feature_table) ## ----echo=FALSE, results='hide'----------------------------------------------- library("rio") export(mtcars, "mtcars.csv") export(mtcars, "mtcars.rds") export(mtcars, "mtcars.dta") export(mtcars, "mtcars_noext", format = "csv") ## ----------------------------------------------------------------------------- library("rio") x <- import("mtcars.csv") y <- import("mtcars.rds") z <- import("mtcars.dta") # confirm identical all.equal(x, y, check.attributes = FALSE) all.equal(x, z, check.attributes = FALSE) ## ----------------------------------------------------------------------------- head(import("mtcars_noext", format = "csv")) ## ----echo=FALSE, results='hide'----------------------------------------------- unlink("mtcars.csv") unlink("mtcars.rds") unlink("mtcars.dta") unlink("mtcars_noext") ## ----------------------------------------------------------------------------- library("rio") export(mtcars, "mtcars.csv") export(mtcars, "mtcars.rds") export(mtcars, "mtcars.dta") ## ----------------------------------------------------------------------------- library("magrittr") mtcars %>% subset(hp > 100) %>% aggregate(. ~ cyl + am, data = ., FUN = mean) %>% export(file = "mtcars2.dta") ## ----------------------------------------------------------------------------- # export to sheets of an Excel workbook export(list(mtcars = mtcars, iris = iris), "multi.xlsx") ## ----------------------------------------------------------------------------- # export to an .Rdata file ## as a named list export(list(mtcars = mtcars, iris = iris), "multi.rdata") ## as a character vector export(c("mtcars", "iris"), "multi.rdata") ## ----------------------------------------------------------------------------- export_list(list(mtcars = mtcars, iris = iris), "%s.tsv") ## ----------------------------------------------------------------------------- # create file to convert export(mtcars, "mtcars.dta") # convert Stata to SPSS convert("mtcars.dta", "mtcars.sav") ## ----------------------------------------------------------------------------- # create an ambiguous file fwf <- tempfile(fileext = ".fwf") cat(file = fwf, "123456", "987654", sep = "\n") # see two ways to read in the file identical(import(fwf, widths = c(1, 2, 3)), import(fwf, widths = c(1, -2, 3))) # convert to CSV convert(fwf, "fwf.csv", in_opts = list(widths = c(1, 2, 3))) import("fwf.csv") # check conversion ## ----echo=FALSE, results='hide'----------------------------------------------- unlink("mtcars.dta") unlink("mtcars.sav") unlink("fwf.csv") unlink(fwf) ## ----echo=FALSE, results='hide'----------------------------------------------- unlink("mtcars.csv") unlink("mtcars.rds") unlink("mtcars.rdata") unlink("mtcars.dta") unlink("multi.xlsx") unlink("multi.rdata") unlink("mtcars2.dta") unlink("mtcars.tsv") unlink("iris.tsv") rio/inst/doc/extension.html0000644000176200001440000003600314502270452015472 0ustar liggesusers Extending rio

Extending rio

library(rio)

rio implements format-specific S3 methods for each type of file that can be imported from or exported to. This happens via internal S3 generics, .import and .export. It is possible to write new methods like with any S3 generic (e.g., print).

As an example, .import.rio_csv imports from a comma-separated values file. If you want to produce a method for a new filetype with extension myfile, you simply have to create a function called .import.rio_myfile that implements a format-specific importing routine and returns a data.frame. rio will automatically recognize new S3 methods, so that you can then import your file using: import("file.myfile").

The way to develop export method is same: .export.rio_csv. The first two parameters of .export are file (file name) and x (data frame to be exported).

As general guidance, if an import method creates many attributes, these attributes should be stored — to the extent possible — in variable-level attributes fields. These can be gathered to the data.frame level by the user via gather_attrs.

Examples

arff

The following example shows how the arff import and export methods are implemented internally.

.import.rio_arff <- function(file, which = 1, ...) {
    foreign::read.arff(file = file)
}
.export.rio_arff <- function(file, x, ...) {
    foreign::write.arff(x = x, file = file, ...)
}

ledger

This is the example from the ledger package (MIT) by Dr Trevor L David .

.import.rio_ledger <- register # nolint
register <- function(file, ..., toolchain = default_toolchain(file), date = NULL) {
    .assert_toolchain(toolchain)
    switch(toolchain,
        "ledger" = register_ledger(file, ..., date = date),
        "hledger" = register_hledger(file, ..., date = date),
        "beancount" = register_beancount(file, ..., date = date),
        "bean-report_ledger" = {
            file <- .bean_report(file, "ledger")
            on.exit(unlink(file))
            register_ledger(file, ..., date = date)
        },
        "bean-report_hledger" = {
            file <- .bean_report(file, "hledger")
            on.exit(unlink(file))
            register_hledger(file, ..., date = date)
        }
    )
}
rio/inst/CITATION0000644000176200001440000000056014476051357013172 0ustar liggesuserscitHeader("To cite package 'rio' in publications use:") bibentry(bibtype = "Manual", title = "rio: A Swiss-army knife for data file I/O", author = c(person("Chung-hong", "Chan"), person("Thomas J.", "Leeper"), person("Jason", "Becker"), person("David", "Schoch")), url = "https://cran.r-project.org/package=rio", year = 2023) rio/po/0000755000176200001440000000000014140045476011466 5ustar liggesusersrio/po/R-rio.pot0000644000176200001440000000641414140045476013207 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: rio 0.5.27\n" "POT-Creation-Date: 2021-06-18 09:36\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "The following arguments were ignored for" msgstr "" msgid ":" msgstr "" msgid "," msgstr "" msgid "condition" msgstr "" msgid "File compression failed for %s!" msgstr "" msgid "Zip archive contains multiple files. Attempting first file." msgstr "" msgid "Tar archive contains multiple files. Attempting first file." msgstr "" msgid "'outfile' is missing with no default" msgstr "" msgid "Must specify 'file' and/or 'format'" msgstr "" msgid "'x' is not a data.frame or matrix" msgstr "" msgid "'x' must be a list. Perhaps you want export()?" msgstr "" msgid "'file' must be a character vector" msgstr "" msgid "'file' must have a %s placehold" msgstr "" msgid "All elements of 'x' must be named or all must be unnamed" msgstr "" msgid "Names of elements in 'x' are not unique" msgstr "" msgid "'file' must be same length as 'x', or a single pattern with a %s placeholder" msgstr "" msgid "File names are not unique" msgstr "" msgid "Export failed for element %d, filename: %s" msgstr "" msgid "data.table::fwrite() does not support writing to connections. Using utils::write.table() instead." msgstr "" msgid "Columns:" msgstr "" msgid "'x' must be a data.frame, list, or environment" msgstr "" msgid "%s format not supported. Consider using the '%s()' function" msgstr "" msgid "Import support for the %s format is exported by the %s package. Run 'library(%s)' then try again." msgstr "" msgid "Format not supported" msgstr "" msgid "'x' is not a data.frame" msgstr "" msgid "No such file" msgstr "" msgid "'data.table = TRUE' argument overruled. Using setclass = '%s'" msgstr "" msgid "Import failed for %s" msgstr "" msgid "Import failed for %s from %s" msgstr "" msgid "Attempt to rbindlist() the data did not succeed. List returned instead." msgstr "" msgid "data.table::fread() does not support reading from connections. Using utils::read.table() instead." msgstr "" msgid "Ambiguous file format ('.dat'), but attempting 'data.table::fread(\"%s\")'" msgstr "" msgid "Import of fixed-width format data requires a 'widths' argument. See ? read.fwf()." msgstr "" msgid "File imported using load. Arguments to '...' ignored." msgstr "" msgid "Dump file contains multiple objects. Returning first object." msgstr "" msgid "File imported using readRDS. Arguments to '...' ignored." msgstr "" msgid "Rdata file contains multiple objects. Returning first object." msgstr "" msgid "Import of Fortran format data requires a 'style' argument. See ? utils::read.fortran()." msgstr "" msgid "The following arguments were ignored for read_ods:" msgstr "" msgid "Requested table exceeds number of tables found in file (" msgstr "" msgid ")!" msgstr "" msgid "Unrecognized file format. Try specifying with the format argument." msgstr "" msgid "'file' is not a string" msgstr "" msgid "'file' has no extension" msgstr "" msgid "last record incomplete, %d line discarded" msgid_plural "last record incomplete, %d lines discarded" msgstr[0] "" msgstr[1] ""