rio/0000755000176200001440000000000014675043102011045 5ustar liggesusersrio/tests/0000755000176200001440000000000014476051106012211 5ustar liggesusersrio/tests/testthat/0000755000176200001440000000000014675043102014047 5ustar liggesusersrio/tests/testthat/test_format_dbf.R0000644000176200001440000000057214612465270017345 0ustar liggesuserstest_that("Export to and import from XBASE (.dbf)", { skip_if_not_installed("foreign") withr::with_tempfile("iris_file", fileext = ".dbf", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) d <- import(iris_file) expect_true(is.data.frame(d)) expect_true(!"factor" %in% vapply(d, class, character(1))) }) }) rio/tests/testthat/test_gather_attrs.R0000644000176200001440000000335714612465270017735 0ustar liggesuserse <- 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)) }) } 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_check_file.R0000644000176200001440000000514014643763372017322 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(NA)) expect_error(.check_file(NA_character_)) expect_error(.check_file(c(NA, "a.csv"))) expect_error(.check_file(c(NA_character_, "a.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_format_eviews.R0000644000176200001440000000025614612465270020113 0ustar liggesuserstest_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_format_pzfx.R0000644000176200001440000000160414612465270017576 0ustar liggesusersskip_if_not_installed("pzfx") test_that("Export to and import from pzfx", { ## pzfx support only numeric data iris_numeric <- iris iris_numeric$Species <- as.numeric(iris_numeric$Species) withr::with_tempfile("iris_file", fileext = ".pzfx", code = { export(iris_numeric, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) ## 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_file)), dim(iris_numeric))) expect_true(identical(dim(import(iris_file, which = "Data 1")), dim(iris_numeric))) expect_true(identical(dim(import(iris_file, table = "Data 1")), dim(iris_numeric))) }) }) rio/tests/testthat/test_guess.R0000644000176200001440000000234514612465270016370 0ustar liggesuserstest_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", { withr::with_tempdir(code = { project_path <- getwd() export(iris, format = "csv") expect_true(file.exists(file.path(project_path, "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_format_rdata.R0000644000176200001440000000456314621337153017707 0ustar liggesuserstest_that("Export to and import from Rdata", { withr::with_tempfile("iris_file", fileext = ".Rdata", code = { ## data frame export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".Rdata", code = { ## environment e <- new.env() e$iris <- iris export(e, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".Rdata", code = { ## character export("iris", iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".Rdata", code = { ## expect error otherwise expect_error(export(iris$Species, iris_file)) }) }) test_that("Export to and import from rda", { withr::with_tempfile("iris_file", fileext = ".rda", code = { ## data frame export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".rda", code = { ## environment e <- new.env() e$iris <- iris export(e, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".rda", code = { ## character export("iris", iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) expect_true(is.data.frame(import(iris_file, which = 1, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".rda", code = { ## expect error otherwise expect_error(export(iris$Species, iris_file)) }) }) rio/tests/testthat/test_format_html.R0000644000176200001440000000447414612657206017565 0ustar liggesusersskip_if_not_installed("xml2") test_html <- function(breaker = "&") { mtcars2 <- mtcars colnames(mtcars2)[1] <- paste0("mp", breaker, breaker, "g") mtcars2[1,1] <- paste0("mp", breaker, breaker, "g") withr::with_tempfile("mtcars_file", fileext = ".html", code = { expect_error(x <- rio::export(mtcars2, mtcars_file), 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 and import from HTML", { withr::with_tempfile("iris_file", fileext = ".html", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file)), label = "import from single-table html works") }) }) test_that("Export to HTML with ampersands",{ withr::with_tempfile("iris_file", fileext = ".html", code = { iris$`R & D` <- paste(sample(letters,nrow(iris), replace = TRUE), "&", sample(LETTERS,nrow(iris), replace = TRUE)) export(iris, iris_file) expect_true(file.exists(iris_file), label = "export to html with ampersands works") }) }) test_that("Import from HTML", { 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", { 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") }) test_that("html with &, >, ', \", >, <", { ## test all useless <- lapply(c("&", "\"", "'", "<", ">"), test_html) }) rio/tests/testthat/test_set_class.R0000644000176200001440000000576314612465270017231 0ustar liggesusersmtcars_tibble <- tibble::as_tibble(mtcars) mtcars_datatable <- data.table::as.data.table(mtcars) test_that("Set object class", { mtcars_tibble <- tibble::as_tibble(mtcars) mtcars_datatable <- data.table::as.data.table(mtcars) 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", { mtcars_tibble <- tibble::as_tibble(mtcars) mtcars_datatable <- data.table::as.data.table(mtcars) 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")) withr::with_tempfile("data_file", fileext = ".csv", code = { export(mtcars, data_file) expect_true(inherits(import(data_file, setclass = "data.table"), "data.table")) expect_true(inherits(import(data_file, data.table = TRUE, setclass = "data.table"), "data.table")) }) }) 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")) withr::with_tempfile("data_file", fileext = ".csv", code = { export(mtcars, data_file) expect_true(inherits(import(data_file, setclass = "arrow"), "ArrowTabular")) expect_true(inherits(import(data_file, data.table = TRUE, setclass = "arrow"), "ArrowTabular")) }) }) test_that("ArrowTabular can be exported", { skip_if(getRversion() <= "4.2") skip_if_not_installed("arrow") mtcars_arrow <- arrow::arrow_table(mtcars) withr::with_tempfile("data_file", fileext = ".csv", code = { expect_error(export(mtcars_arrow, data_file), NA) ## no concept of rownames expect_true(inherits(import(data_file), "data.frame")) }) }) test_that("Simulate arrow is not installed, #376", { ## although this is pretty meaningless withr::with_tempfile("data_file", fileext = ".csv", code = { with_mocked_bindings({ export(mtcars, data_file) expect_error(import(data_file, 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_export_list.R0000644000176200001440000000761314643571002017614 0ustar liggesuserslibrary("datasets") test_that("export_list() works", { withr::with_tempdir({ export(list( mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ] ), "mtcars.xlsx") mylist <- import_list("mtcars.xlsx") 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") }) }) test_that("archive formats, #415", { skip_if(getRversion() <= "4.0") withr::with_tempdir({ mylist <- list(mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ]) expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.gz"), "specified but format is not supported") expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.bz2"), "specified but format is not supported") expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.zip"), NA) expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.tar"), NA) expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.tar.gz"), NA) expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.tar.bz2"), NA) }) }) test_that("List length of one, #385", { withr::with_tempdir({ example1 <- list("iris" = iris) tempfile <- tempfile(fileext = ".csv") expect_error(export(example1, tempfile), NA) tempfile <- tempfile(fileext = ".xlsx") expect_error(export(example1, tempfile), NA) expect_equal(readxl::excel_sheets(tempfile), "iris") ## name is retained tempfile <- tempfile(fileext = ".rds") expect_error(export(example1, tempfile), NA) expect_true(is.list(readRDS(tempfile)) && !is.data.frame(readRDS(tempfile))) }) }) test_that("tar export error for R < 4.0.3", { skip_if(getRversion() >= "4.0.3") withr::with_tempdir({ mylist <- list(mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ]) expect_error(export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "archive.csv.tar"), "^Exporting") }) }) rio/tests/testthat/test_format_sav.R0000644000176200001440000000575714612465270017415 0ustar liggesusers test_that("Export to SPSS (.sav)", { 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" withr::with_tempfile("mtcars_file", fileext = ".sav", code = { export(mtcars2, mtcars_file) expect_true(file.exists(mtcars_file)) expect_true(d <- is.data.frame(import(mtcars_file))) expect_true(!"labelled" %in% unlist(lapply(d, class))) ##Variable label and value labels preserved on SPSS (.sav) roundtrip d <- import(mtcars_file) 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")) ##haven is deprecated" lifecycle::expect_deprecated(import(mtcars_file, haven = TRUE)) lifecycle::expect_deprecated(import(mtcars_file, haven = FALSE)) }) }) test_that("Export to SPSS compressed (.zsav)", { 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" withr::with_tempfile("mtcars_file", fileext = ".zsav", code = { export(mtcars2, mtcars_file) expect_true(file.exists(mtcars_file)) expect_true(d <- is.data.frame(import(mtcars_file))) expect_true(!"labelled" %in% unlist(lapply(d, class))) d <- import(mtcars_file) 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")) }) }) rio/tests/testthat/test_format_qs.R0000644000176200001440000000042514612465270017232 0ustar liggesusersskip_if_not_installed("qs") test_that("Export to and import from qs", { withr::with_tempfile("iris_file", fileext = ".qs", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) rio/tests/testthat/test_mapping.R0000644000176200001440000000273614612465270016701 0ustar liggesuserstest_that("mapping; both base and tidy conventions work", { withr::with_tempfile("tempxlsx", fileext = ".xlsx", code = { 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", { withr::with_tempfile("tempxlsx", fileext = ".xlsx", code = { 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", { withr::with_tempfile("tempxlsx", fileext = ".xlsx", code = { 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_format_json.R0000644000176200001440000000173714612465270017567 0ustar liggesusersskip_if_not_installed("jsonlite") test_that("Export to and import from JSON", { withr::with_tempfile("iris_file", fileext = ".json", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) test_that("Export to JSON (non-data frame)", { withr::with_tempfile("list_file", fileext = ".json", code = { export(list(1:10, letters), list_file) expect_true(file.exists(list_file)) expect_true(inherits(import(list_file), "list")) expect_false(inherits(import(list_file), "data.frame")) expect_true(length(import(list_file)) == 2L) }) }) test_that("utf-8", { content <- c("\"", "\u010d", "\u0161", "\u00c4", "\u5b57", "\u30a2", "\u30a2\u30e0\u30ed") x <- data.frame(col = content) withr::with_tempfile("tempjson", fileext = ".json", code = { y <- import(export(x, tempjson)) testthat::expect_equal(content, y$col) }) }) rio/tests/testthat/test_export_corner_cases.R0000644000176200001440000000212714612465270021307 0ustar liggesuserstest_that("export to nonexisting directory #347", { withr::with_tempdir({ output_dir <- file.path(".", "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"))) }) }) test_that("export to existing directory (contra previous one) #347", { withr::with_tempdir({ output_dir <- file.path(".", "this_surely_exist1") dir.create(output_dir, recursive = TRUE) ## right? 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"))) }) }) test_that("export to nonexisting directory also for compressed file #347", { withr::with_tempdir({ output_dir <- file.path(".", "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"))) }) }) rio/tests/testthat/test_identical.R0000644000176200001440000000443314621337153017174 0ustar liggesuserstest_that("Data identical (text formats)", { withr::with_tempdir(code = { expect_equivalent(import(export(mtcars, "mtcars.txt")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.csv")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.tsv")), mtcars) }) }) test_that("Data identical (R formats)", { withr::with_tempdir(code = { expect_equivalent(import(export(mtcars, "mtcars.rds"), trust = TRUE), mtcars) expect_equivalent(import(export(mtcars, "mtcars.R"), trust = TRUE), mtcars) expect_equivalent(import(export(mtcars, "mtcars.RData"), trust = TRUE), mtcars) expect_equivalent(import(export(mtcars, "mtcars.R", format = "dump"), trust = TRUE), mtcars) }) }) test_that("Data identical (R formats), feather", { skip_if_not_installed("arrow") withr::with_tempdir(code = { expect_equivalent(import(export(mtcars, "mtcars.feather")), mtcars) }) }) test_that("Data identical (haven formats)", { withr::with_tempdir(code = { expect_equivalent(import(export(mtcars, "mtcars.dta")), mtcars) expect_equivalent(import(export(mtcars, "mtcars.sav")), mtcars) }) }) test_that("Data identical (Excel formats)", { withr::with_tempdir(code = { expect_equivalent(import(export(mtcars, "mtcars.xlsx")), mtcars) }) }) test_that("Data identical (other formats)", { skip_if_not_installed("xml2") skip_if_not_installed("jsonlite") withr::with_tempdir(code = { 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) }) }) test_that("Data identical (optional arguments)", { withr::with_tempdir(code = { ##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)) }) }) rio/tests/testthat/test_import_list.R0000644000176200001440000002154214622630120017574 0ustar liggesuserstest_that("Data identical (import_list)", { withr::with_tempfile("mtcars_file", fileext = ".rds", code = { export(mtcars, mtcars_file) expect_equivalent(import_list(rep(mtcars_file, 2), trust = TRUE), list(mtcars, mtcars)) mdat <- rbind(mtcars, mtcars) dat <- import_list(rep(mtcars_file, 2), rbind = TRUE, trust = 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()", { withr::with_tempfile("rdata_file", fileext = ".rdata", code = { export(list(mtcars = mtcars, iris = iris), rdata_file) dat <- import_list(rdata_file, trust = TRUE) 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", { withr::with_tempfile("temphtm", fileext = ".htm", code = { 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", { withr::with_tempfile("data_file", fileext = ".xlsx", code = { export(list(a = mtcars, b = iris), data_file) expect_true(identical(names(import_list(data_file)), c("a", "b"))) expect_true(identical(names(import_list(data_file, which = 1)), "a")) expect_true(identical(names(import_list(data_file, which = "a")), "a")) expect_true(identical(names(import_list(data_file, which = 2)), "b")) expect_true(identical(names(import_list(data_file, which = "b")), "b")) expect_true(identical(names(import_list(data_file, which = 1:2)), c("a", "b"))) expect_true(identical(names(import_list(data_file, which = 2:1)), c("b", "a"))) expect_true(identical(names(import_list(data_file, which = c("a", "b"))), c("a", "b"))) expect_true(identical(names(import_list(data_file, which = c("b", "a"))), c("b", "a"))) }) }) test_that("Import single file via import_list()", { withr::with_tempfile("data_file", fileext = ".rds", code = { export(mtcars, data_file) expect_true(identical(import_list(data_file, rbind = TRUE, trust = TRUE), mtcars)) }) }) test_that("Import single file from zip via import_list()", { withr::with_tempfile("data_file", fileext = ".csv.zip", code = { export(mtcars, data_file, format = "csv") expect_true(is.data.frame(import_list(data_file)[[1L]])) expect_true(is.data.frame(import_list(data_file, which = 1)[[1L]])) basefile_name <- gsub(".zip$", "", basename(data_file)) expect_true(is.data.frame(import_list(data_file, which = basefile_name)[[1L]])) }) }) test_that("Import multiple files from zip via import_list()", { withr::with_tempfile("data_file", fileext = ".csv.zip", code = { mylist <- list(mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ]) expect_error(export_list(mylist, file = paste0("mtcars", 1:3, ".csv"), archive = data_file), NA) expect_error(res <- import_list(data_file), NA) expect_true(is.list(res)) expect_equal(length(res), 3) expect_true(is.data.frame(res[[1]])) expect_true(is.data.frame(res[[2]])) expect_true(is.data.frame(res[[3]])) }) }) test_that("Import multiple files from zip via import_list()", { skip_if(getRversion() <= "4.0") withr::with_tempfile("data_file", fileext = ".csv.tar.gz", code = { mylist <- list(mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ]) expect_error(export_list(mylist, file = paste0("mtcars", 1:3, ".csv"), archive = data_file), NA) expect_error(res <- import_list(data_file), NA) expect_true(is.list(res)) expect_equal(length(res), 3) expect_true(is.data.frame(res[[1]])) expect_true(is.data.frame(res[[2]])) expect_true(is.data.frame(res[[3]])) }) }) test_that("Using setclass in import_list()", { withr::with_tempfile("data_file", fileext = ".rds", code = { export(mtcars, data_file) dat1 <- import_list(rep(data_file, 2), setclass = "data.table", rbind = TRUE, trust = TRUE) expect_true(inherits(dat1, "data.table")) dat2 <- import_list(rep(data_file, 2), setclass = "tbl", rbind = TRUE, trust = TRUE) expect_true(inherits(dat2, "tbl")) }) }) test_that("Object names are preserved by import_list()", { withr::with_tempdir(code = { 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) }) }) test_that("File names are added as attributes by import_list()", { withr::with_tempdir(code = { 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) }) }) 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) { withr::with_tempfile("tempzip", fileext = paste0(".", format, ".zip"), code = { 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") skip_on_os("mac") ## apache/arrow#40991 formats <- c("qs", "parquet", "ods") for (format in formats) { withr::with_tempfile("tempzip", fileext = paste0(".", format, ".zip"), code = { rio::export(mtcars, tempzip, format = format) expect_warning(rio::import(tempzip), NA) expect_warning(rio::import_list(tempzip), NA) }) } }) test_that("Informative message when files are not found #389", { withr::with_tempfile("mtcars_file", fileext = ".rds", code = { export(mtcars, mtcars_file) expect_true(file.exists(mtcars_file)) expect_false(file.exists("nonexisting.rds")) expect_warning(import_list(c(mtcars_file, "nonexisting.rds"), trust = TRUE), "^Import failed for nonexisting") }) }) test_that("Missing files and rbind", { withr::with_tempfile("mtcars_file", fileext = ".rds", code = { export(mtcars, mtcars_file) expect_true(file.exists(mtcars_file)) expect_false(file.exists("nonexisting.rds")) expect_false(file.exists("nonexisting2.rds")) expect_warning(x <- import_list(c(mtcars_file, "nonexisting.rds"), rbind = TRUE, trust = TRUE), "^Import failed for nonexisting") expect_true(is.data.frame(x)) expect_warning(x <- import_list(c("nonexisting.rds", "nonexisting2.rds"), rbind = TRUE, trust = TRUE), "^Import failed for nonexisting") }) }) rio/tests/testthat/test_trust.R0000644000176200001440000000553014672241272016422 0ustar liggesuserstest_that("Deprecation of untrusted dump", { withr::with_tempfile("iris_file", fileext = ".dump", code = { export(iris, iris_file) ## expect deprecation to work expect_warning(import(iris_file), regexp = "set to FALSE by default") ## expect false to error expect_error(import(iris_file, trust = FALSE)) }) }) test_that("Deprecation of untrusted Rdata", { withr::with_tempfile("iris_file", fileext = ".Rdata", code = { export(iris, iris_file) ## expect deprecation to work expect_warning(import(iris_file), regexp = "set to FALSE by default") ## expect false to error expect_error(import(iris_file, trust = FALSE)) }) }) test_that("Deprecation of untrusted rds", { withr::with_tempfile("iris_file", fileext = ".rds", code = { export(iris, iris_file) ## expect deprecation to work expect_warning(import(iris_file), regexp = "set to FALSE by default") ## expect false to error expect_error(import(iris_file, trust = FALSE)) }) }) test_that("No deprecation warning if `trust` is explicit", { withr::with_tempfile("iris_file", fileext = ".rds", code = { export(iris, iris_file) expect_silent(import(iris_file, trust = TRUE)) expect_error(import(iris_file, trust = FALSE)) ## no warning right? }) }) test_that("Undocumented feature, options", { withr::with_options(list(rio.import.trust = TRUE), { withr::with_tempfile("iris_file", fileext = ".rds", code = { export(iris, iris_file) expect_silent(import(iris_file)) expect_error(import(iris_file), NA) }) }) withr::with_options(list(rio.import.trust = FALSE), { withr::with_tempfile("iris_file", fileext = ".rds", code = { export(iris, iris_file) expect_error(import(iris_file)) }) }) }) test_that("`trust` wont cause problems for other import methods", { withr::with_tempfile("iris_file", fileext = ".xlsx", code = { export(iris, iris_file) expect_silent(import(iris_file, trust = TRUE)) expect_error(import(iris_file, trust = FALSE), NA) }) }) test_that("`trust` for import_list()", { withr::with_tempfile("iris_file", fileext = ".rdata", code = { export(iris, iris_file) expect_warning(import_list(iris_file), regexp = "set to FALSE by default") expect_silent(import_list(iris_file, trust = TRUE)) expect_error(import_list(iris_file, trust = FALSE)) }) }) test_that("`trust` wont cause problems for other formats in import_list", { withr::with_tempfile("data_file", fileext = ".xlsx", code = { export(list(a = mtcars, b = iris), data_file) expect_silent(import(data_file)) expect_silent(import(data_file, trust = TRUE)) expect_error(import(data_file, trust = FALSE), NA) }) }) rio/tests/testthat/test_format_matlab.R0000644000176200001440000000060514612465270020047 0ustar liggesusersskip_if_not_installed("rmatio") test_that("Export to and import from matlab", { skip("failing mysteriously") withr::with_tempfile("iris_file", fileext = ".matlab", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) expect_true(identical(dim(import(iris_file)), dim(iris))) }) }) rio/tests/testthat/test_format_fortran.R0000644000176200001440000000045314612465270020263 0ustar liggesuserstest_that("Import from Fortran", { ## no fixed file extension withr::with_tempfile("fortran_file", code = { cat(file = fortran_file, "123456", "987654", sep = "\n") expect_true(is.data.frame(import(fortran_file, format = "fortran", style = c("F2.1","F2.0","I2")))) }) }) rio/tests/testthat/test_format_external_packages.R0000644000176200001440000000130614612465270022266 0ustar liggesuserstest_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) { withr::with_tempfile("dummyfile", fileext = paste0(".", ext), code = { file.create(dummyfile) expect_error(import(dummyfile)) }) } }) test_that("import method exported by an external package", { extensions <- c("bean", "beancount", "ledger", "hledger") for (ext in extensions) { withr::with_tempfile("dummyfile", fileext = paste0(".", ext), code = { file.create(dummyfile) expect_error(import(dummyfile)) }) } }) rio/tests/testthat/test_errors.R0000644000176200001440000000310714612465270016553 0ustar liggesuserslibrary("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", { withr::with_tempfile("test_file", fileext = ".faketype", code = { writeLines("123", con = test_file) expect_error(import(test_file), "Format not supported") expect_error(export(mtcars, test_file), "Format not supported") }) expect_equal(.standardize_format("faketype"), "faketype") expect_error(get_ext("noextension"), "'file' has no extension") }) test_that("Error for mixed support file types", { expect_error(import("test.por"), "No such file") withr::with_tempfile("mtcars_file", fileext = ".por", code = { expect_error(export(mtcars, mtcars_file), "Format not supported") }) }) test_that("Only export data.frame or matrix", { withr::with_tempfile("test_file", fileext = ".csv", code = { expect_error(export(1, test_file), "'x' is not a data.frame or matrix") }) }) test_that("Column widths printed for fixed-width format", { withr::with_tempfile("test_file", fileext = ".txt", code = { expect_true(is.character(export(data.frame(1), test_file, format = "fwf", verbose = FALSE))) expect_message(export(data.frame(1), test_file, format = "fwf", verbose = TRUE)) }) }) test_that("Warning for import_list() with missing file", { expect_warning(import_list("fake_file.csv")) ## no error }) rio/tests/testthat/test_suggestions.R0000644000176200001440000000166714674546115017630 0ustar liggesuserstest_that("uninstalled_formats()", { skip_on_cran() formats <- uninstalled_formats() if (is.null(formats)) { expect_true(install_formats()) } else { expect_type(formats, "character") } }) test_that("show_unsupported_formats (in the fully supported environment) on CI", { skip_on_cran() for (pkg in attr(rio_formats, "suggested_packages")) { skip_if_not_installed(pkg) } expect_false(show_unsupported_formats()) expect_message(show_unsupported_formats(), "All default") }) test_that("show_unsupported_formats (in the partial supported environment) on CI", { skip_on_cran() fake_uninstalled_formats <- function() { return(c("readODS")) } with_mocked_bindings(code = { expect_true(show_unsupported_formats()) expect_message(show_unsupported_formats(), "These formats are not supported") }, `uninstalled_formats` = fake_uninstalled_formats) }) rio/tests/testthat/test_format_tsv.R0000644000176200001440000000102614612465270017421 0ustar liggesuserstest_that("Export to and import from TSV", { withr::with_tempfile("iris_file", fileext = ".tsv", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) test_that("fread is deprecated", { withr::with_tempfile("iris_file", fileext = ".tsv", code = { export(iris, iris_file) lifecycle::expect_deprecated(import(iris_file, fread = TRUE)) lifecycle::expect_deprecated(import(iris_file, fread = FALSE)) }) }) rio/tests/testthat/test_format_ods.R0000644000176200001440000000402714612465270017376 0ustar liggesusersskip_if_not_installed("readODS") test_that("Import from ODS", { 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 and import from ODS", { withr::with_tempfile("iris_file", fileext = ".ods", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) test_that("... correctly passed #318", { withr::with_tempfile("mtcars_file", fileext = ".ods", code = { export(iris, mtcars_file, sheet = "mtcars") expect_equal(readODS::list_ods_sheets(mtcars_file), "mtcars") }) }) test_that("Export and Import FODS", { withr::with_tempfile("fods_file", fileext = ".fods", code = { export(iris, fods_file) expect_true(file.exists(fods_file)) expect_true(is.data.frame(import(fods_file))) export(iris, fods_file, sheet = "mtcars") expect_equal(readODS::list_fods_sheets(fods_file), "mtcars") expect_error(y <- import(fods_file), NA) expect_true(is.data.frame(y)) }) }) test_that("Export list of data frames", { withr::with_tempfile("ods_files", fileext = c(".ods", ".fods"), code = { dfs <- list("cars" = mtcars, "flowers" = iris) expect_error(export(dfs, ods_files[1]), NA) expect_error(export(dfs, ods_files[2]), NA) expect_equal(import(ods_files[1], which = "flowers"), import(ods_files[2], which = "flowers")) }) }) rio/tests/testthat/test_convert.R0000644000176200001440000000224514612465270016721 0ustar liggesuserslibrary("datasets") test_that("Basic file conversion", { withr::with_tempfile("mtcars_files", fileext = c(".dta", ".csv"), code = { export(mtcars, mtcars_files[1]) convert(mtcars_files[1], mtcars_files[2]) convert(mtcars_files[2], mtcars_files[1]) x <- import(mtcars_files[1]) expect_true(identical(names(mtcars), names(x))) expect_true(identical(dim(mtcars), dim(x))) }) }) test_that("File conversion with arguments", { withr::with_tempfile("mtcars_files", fileext = c(".csv", ".tsv"), code = { export(mtcars, mtcars_files[1], format = "tsv") convert(mtcars_files[1], mtcars_files[1], in_opts = list(format = "tsv")) expect_true(file.exists(mtcars_files[1])) expect_true(!file.exists(mtcars_files[2])) convert(mtcars_files[1], mtcars_files[2], in_opts = list(format = "tsv"), out_opts = list(format = "csv")) expect_true(file.exists(mtcars_files[2])) }) }) test_that("File conversion w/o out_file errors", { withr::with_tempfile("mtcars_file", fileext = ".dta", { export(mtcars, mtcars_file) expect_error(convert(mtcars_file)) }) }) rio/tests/testthat/test_matrix.R0000644000176200001440000000077114612465270016547 0ustar liggesuserstest_that("Export matrix to and import from CSV", { withr::with_tempfile("temp_files", fileext = c(".csv", ".csv"), code = { export(warpbreaks, temp_files[1]) export(as.matrix(warpbreaks), temp_files[2]) expect_true(file.exists(temp_files[1])) expect_true(file.exists(temp_files[2])) expect_true(identical(import(temp_files[1], colClasses = rep("character", 3)), import(temp_files[2], colClasses = rep("character", 3)))) }) }) 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_yml.R0000644000176200001440000000142214612465270017406 0ustar liggesusersskip_if_not_installed("yaml") test_that("Export to and import from YAML", { withr::with_tempfile("iris_file", fileext = ".yaml", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) expect_identical(import(iris_file)[, 1:4], iris[, 1:4]) expect_identical(import(iris_file)$Species, as.character(iris$Species)) }) }) test_that("utf-8", { skip_if(getRversion() <= "4.2") withr::with_tempfile("tempyaml", fileext = ".yaml", code = { content <- c("\"", "\u010d", "\u0161", "\u00c4", "\u5b57", "\u30a2", "\u30a2\u30e0\u30ed") x <- data.frame(col = content) y <- import(export(x, tempyaml)) testthat::expect_equal(content, y$col) }) }) rio/tests/testthat/test_format_dif.R0000644000176200001440000000025014612465270017345 0ustar liggesuserstest_that("Import from DIF", { dd <- import(file.path(system.file("misc", package = "utils"), "exDIF.dif"), transpose = TRUE) expect_true(is.data.frame(dd)) }) rio/tests/testthat/test_format_sas.R0000644000176200001440000000075014612465270017376 0ustar liggesuserstest_that("Export to and import from SAS (.xpt)", { withr::with_tempfile("mtcars_file", fileext = ".xpt", code = { export(mtcars, mtcars_file) expect_true(file.exists(mtcars_file)) expect_true(is.data.frame(import(mtcars_file))) }) }) test_that("Export SAS (.sas7bdat)", { withr::with_tempfile("mtcars_file", fileext = ".sas7bdat", code = { suppressWarnings(export(mtcars, mtcars_file)) expect_true(file.exists(mtcars_file)) }) }) rio/tests/testthat/test_format_mtp.R0000644000176200001440000000004714612465270017407 0ustar liggesusers##test_that("Import from Minitab", {}) rio/tests/testthat/test_format_rec.R0000644000176200001440000000004614612465270017357 0ustar liggesusers#test_that("Import from Epiinfo", {}) rio/tests/testthat/test_format_xml.R0000644000176200001440000000161714612465270017413 0ustar liggesusersskip_if_not_installed("xml2") test_xml <- function(breaker = "&") { mtcars2 <- mtcars colnames(mtcars2)[1] <- paste0("mp", breaker, breaker, "g") mtcars2[1,1] <- paste0("mp", breaker, breaker, "g") withr::with_tempfile("mtcars_file", fileext = ".xml", code = { expect_error(x <- rio::export(mtcars2, mtcars_file), NA) temp_df <- rio::import(mtcars_file) expect_equal(colnames(temp_df)[1], paste0("mp..g")) expect_equal(temp_df[1,1], paste0("mp", breaker, breaker, "g")) }) } test_that("Export to and import from XML", { withr::with_tempfile("iris_file", fileext = ".xml", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) test_that("Export to XML with &, >, ', \", >, <",{ ## test all useless <- lapply(c("&", "\"", "'", "<", ">"), test_xml) }) rio/tests/testthat/test_compress.R0000644000176200001440000001417614643763372017112 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.gz") expect_true(rio:::find_compress("file.gzip")$compress == "gzip") expect_true(rio:::find_compress("file.gz")$compress == "gzip") expect_true(is.na(rio:::find_compress("file.notcompressed")$compress)) }) test_that("Export to compressed (zip, tar) / import", { skip_if(getRversion() <= "4.0") formats <- c("zip", "tar", "tar.gz", "tgz", "tar.bz2", "tbz2") for (format in formats) { withr::with_tempfile("iris_path", fileext = paste0(".csv.", format), code = { e1 <- export(iris, iris_path) expect_true(file.exists(iris_path)) expect_true(is.data.frame(import(iris_path))) expect_true(is.data.frame(import(iris_path, which = 1))) base_file_name <- gsub(paste0("\\.", format), "", basename(iris_path)) expect_true(is.data.frame(import(iris_path, which = base_file_name))) if (format %in% c("tar.gz", "tgz")) { expect_true(R.utils::isGzipped(iris_path, method = "content")) } if (format %in% c("tar.bzip2", "tbz2")) { expect_true(R.utils::isBzipped(iris_path, method = "content")) } }) } }) test_that("Multi-item zip", { formats <- c("zip") for (format in formats) { withr::with_tempfile("iris_path", fileext = paste0(".csv.", format), code = { list_of_df <- list(mtcars1 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars3 = mtcars[21:32, ]) export_list(list_of_df, file = "%s.csv", archive = iris_path) y <- import(iris_path) expect_true(is.data.frame(y)) expect_silent(z1 <- import(iris_path, which = 1)) expect_silent(z2 <- import(iris_path, which = 2)) expect_true(identical(y, z1)) expect_false(identical(y, z2)) }) } }) test_that("Export to compressed (gz, bz2) / import", { formats <- c("gz", "gzip", "bz2", "bzip2") for (format in formats) { withr::with_tempfile("iris_path", fileext = paste0(".csv.", format), code = { e1 <- export(iris, iris_path) expect_true(file.exists(iris_path)) expect_true(is.data.frame(import(iris_path))) if (format %in% c("gzip", "gz")) { expect_true(R.utils::isGzipped(iris_path, method = "content")) } if (format %in% c("bzip2", "bz2")) { expect_true(R.utils::isBzipped(iris_path, method = "content")) } }) } }) test_that("Prevent the reuse of `which` for zip and tar", { skip_if(getRversion() <= "4.0") formats <- c("zip", "tar", "tar.gz", "tgz", "tar.bz2", "tbz2") for (format in formats) { withr::with_tempfile("data_path", fileext = paste0(".xlsx.", format), code = { rio::export(list(some_iris = head(iris)), data_path) expect_error(import(data_path), NA) raw_file <- .list_archive(data_path, find_compress(data_path)$compress)[1] expect_error(import(data_path, which = raw_file), NA) expect_error(suppressWarnings(import(data_path, which = "some_iris"))) }) } ## but not for non-archive format, e.g. .xlsx.gz formats <- c("gz", "bz2") for (format in formats) { withr::with_tempfile("data_path", fileext = paste0(".xlsx.", format), code = { rio::export(list(some_iris = head(iris)), data_path) expect_error(import(data_path), NA) expect_error(import(data_path, which = "some_iris"), NA) }) } }) test_that(".check_tar_support ref #421", { expect_error(.check_tar_support("tar", R_system_version("4.0.2")), "^Exporting") expect_error(.check_tar_support("tar.gz", R_system_version("4.0.2")), "^Exporting") expect_error(.check_tar_support("tar.bz2", R_system_version("4.0.2")), "^Exporting") expect_error(.check_tar_support("tar", R_system_version("4.0.3")), NA) expect_error(.check_tar_support("tar.gz", R_system_version("4.0.3")), NA) expect_error(.check_tar_support("tar.bz2", R_system_version("4.0.3")), NA) expect_error(.check_tar_support("zip", R_system_version("4.0.2")), NA) expect_error(.check_tar_support(NA, R_system_version("4.0.2")), NA) }) test_that("tar export error for R < 4.0.3", { skip_if(getRversion() >= "4.0.3") withr::with_tempfile("iris_path", fileext = paste0(".csv.", "tar"), code = { expect_error(export(iris, iris_path), "^Exporting") }) }) test_that("Wild zip and tar ref $425", { skip_if(getRversion() <= "4.0") ##skip_on_os("windows") withr::with_tempfile("test_files", fileext = c(".csv", ".zip"), code = { filename <- test_files[1] zip_file <- test_files[2] write.csv(1, filename) zip(zip_file, filename) expect_error(rio::import(zip_file), NA) }) for (tar_format in c("tar", "tar.gz", "tar.bz2")) { withr::with_tempfile("test_files", fileext = c(".csv", paste0(".", tar_format)), code = { filename <- test_files[1] tar_file <- test_files[2] write.csv(1, filename) compress_out(tar_file, filename, type = tar_format) expect_error(rio::import(tar_file), NA) }) } }) test_that("Relative path #438", { ## see test_export_list.R withr::with_tempdir({ mylist <- list( mtcars3 = mtcars[1:10, ], mtcars2 = mtcars[11:20, ], mtcars1 = mtcars[21:32, ] ) rio::export_list(mylist, file = paste0("file_", 1:3, ".csv"), archive = "arch/archive.zip") expect_true(file.exists("arch/archive.zip")) }) }) test_that("Integration test #435", { ## filter out all NA cases so that #437 works withr::with_tempfile("iris_path", fileext = "csv.zip", code = { expect_error(rio::export(iris, NA), "must be character") ## strange to be honest expect_error(rio::export(iris, NA_character_), "must not be NA") }) }) rio/tests/testthat/test_format_psv.R0000644000176200001440000000103014612465270017410 0ustar liggesuserstest_that("Export to and import from PSV", { withr::with_tempfile("iris_file", fileext = ".psv", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) test_that("fread is deprecated", { withr::with_tempfile("iris_file", fileext = ".psv", code = { export(iris, iris_file) lifecycle::expect_deprecated(import(iris_file, fread = TRUE)) lifecycle::expect_deprecated(import(iris_file, fread = FALSE)) }) }) rio/tests/testthat/test_remote.R0000644000176200001440000000414214614503454016531 0ustar liggesusersskip_on_cran() 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/gesistsa/rio/main/tests/testdata/noheader.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") } ## short url payload <- try(import("https://is.gd/NLAxtg")) if (!inherits(payload, "try-error")) { expect_true(inherits(payload, "data.frame"), label = "Import remote file from shorten url (implied format)") } ## no extension noextension_url <- "https://github.com/gesistsa/rio/raw/main/tests/testdata/iris_no_extension_xls" expect_error(import(noextension_url)) expect_error(import(noextension_url, format = "xls"), NA) }) 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_xls.R0000644000176200001440000000357614612465270017427 0ustar liggesuserstest_that("Export to Excel (.xlsx)", { withr::with_tempfile("iris_file", fileext = ".xlsx", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) expect_true(is.data.frame(import(iris_file, sheet = 1))) expect_true(is.data.frame(import(iris_file, which = 1))) expect_true(nrow(import(iris_file, n_max = 42)) == 42) }) }) test_that("Expert to Excel (.xlsx) a list", { withr::with_tempfile("tempxlsx", fileext = ".xlsx", code = { 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?", { withr::with_tempfile("tempxlsx", fileext = ".xlsx", code = { 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", { withr::with_tempfile("iris_file", fileext = ".xlsx", code = { export(iris, iris_file) lifecycle::expect_deprecated(import(iris_file, readxl = TRUE)) lifecycle::expect_deprecated(import(iris_file, readxl = FALSE)) }) }) 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))) }) rio/tests/testthat/test_format_dta.R0000644000176200001440000000312114612465270017353 0ustar liggesuserstest_that("Export to Stata", { withr::with_tempfile("mtcars_file", fileext = ".dta", code = { export(mtcars, mtcars_file) expect_true(file.exists(mtcars_file)) mtcars3 <- mtcars names(mtcars3)[1] <- "foo.bar" expect_error(export(mtcars3, mtcars_file), label = "Export fails on invalid Stata names") }) }) test_that("Import from Stata (read_dta)", { withr::with_tempfile("mtcars_file", fileext = ".dta", code = { export(mtcars, mtcars_file) expect_true(is.data.frame(import(mtcars_file))) ## arguments ignored expect_error(import(mtcars_file, extraneous.argument = TRUE), NA) expect_silent(import(mtcars_file,extraneous.argument = TRUE)) }) }) test_that("Import from Stata with extended Haven features (read_dta)", { withr::with_tempfile("mtcars_file", fileext = ".dta", code = { export(mtcars, mtcars_file) expect_true(is.data.frame(mtcars_wtam <- import(mtcars_file, 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", { withr::with_tempfile("mtcars_file", fileext = ".dta", code = { export(mtcars, mtcars_file) lifecycle::expect_deprecated(import(mtcars_file, haven = TRUE)) lifecycle::expect_deprecated(import(mtcars_file, haven = FALSE)) }) }) rio/tests/testthat/test_format_parquet.R0000644000176200001440000000052014650747025020267 0ustar liggesusersskip_if_not_installed("nanoparquet") skip_on_os("mac") ## apache/arrow#40991 test_that("Export to and import from parquet", { withr::with_tempfile("iris_path", fileext = ".parquet", code = { export(iris, iris_path) expect_true(file.exists(iris_path)) expect_true(is.data.frame(import(iris_path))) }) }) rio/tests/testthat/test_format_rds.R0000644000176200001440000000114714621337153017377 0ustar liggesuserstest_that("Export to and import from rds", { withr::with_tempfile("iris_file", fileext = ".rds", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) }) }) test_that("Export to rds (non-data frame)", { withr::with_tempfile("list_file", fileext = ".rds", code = { export(list(1:10, letters), list_file) expect_true(file.exists(list_file)) expect_true(inherits(import(list_file, trust = TRUE), "list")) expect_true(length(import(list_file, trust = TRUE)) == 2L) }) }) rio/tests/testthat/test_format_syd.R0000644000176200001440000000024514612465270017406 0ustar liggesusersskip_if_not_installed("foreign") test_that("Import from Systat", { expect_true(is.data.frame(import(system.file("files/Iris.syd", package = "foreign")[1]))) }) rio/tests/testthat/test_format_fwf.R0000644000176200001440000000272414612465270017375 0ustar liggesuserssimport <- function(...) { suppressWarnings(import(...)) } test_that("Export to and import from FWF .fwf", { withr::with_tempfile("iris_file", fileext = ".fwf", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(simport(iris_file, widths = c(3, 3, 3, 3, 1)))) expect_true(is.data.frame(simport(iris_file, widths = list(c(3, 3, 3, 3, 1))))) expect_true(is.data.frame(simport(iris_file, widths = c(3, 3, 3, 3, 1), col.names = names(iris)))) ## negative column widths expect_true(is.data.frame(simport(iris_file, widths = c(-3, 3, 3, 3, 1)))) ##use col_position instead expect_error(x <- import(iris_file, col_position = readr::fwf_widths(c(1, 3, 3, 3, 1), col_names = names(iris))), NA) expect_equal(x[1,1, drop = TRUE], 5) }) }) test_that("Export to and import from FWF .txt", { withr::with_tempfile("iris_file", fileext = ".txt", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(simport(iris_file, widths = c(3, 3, 3, 3, 1), format = "fwf"))) }) }) test_that("Deprecation of `width` and `col.names`", { withr::with_tempfile("iris_file", fileext = ".fwf", code = { export(iris, iris_file) lifecycle::expect_deprecated(import(iris_file, widths = c(-3, 3, 3, 3, 1))) lifecycle::expect_deprecated(import(iris_file, col.names = names(iris))) }) }) rio/tests/testthat/test_format_csv.R0000644000176200001440000000611714631522466017410 0ustar liggesusersrequire("datasets") test_that("Export to CSV", { withr::with_tempfile("iris_file", fileext = ".csv", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) }) }) test_that("Export (Append) to CSV", { withr::with_tempfile("iris_file", fileext = ".csv", code = { export(iris, iris_file) nlines <- length(readLines(iris_file)) export(iris, iris_file, append = FALSE) expect_true(identical(length(readLines(iris_file)), nlines)) export(iris, iris_file, append = TRUE) expect_true(identical(length(readLines(iris_file)), (2L * nlines) - 1L)) }) }) 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", { withr::with_tempfile("iris_file", fileext = ".csv", code = { write.table(iris, iris_file, dec = ",", sep = ";", row.names = FALSE) expect_true(file.exists(iris_file)) ## import works (even if column classes are incorrect) expect_true(is.data.frame(import(iris_file, header = TRUE))) iris_imported <- import(iris_file, 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"]])) }) }) test_that("Export to and Import from CSV2", { withr::with_tempfile("iris_file", fileext = ".csv", code = { export(iris, iris_file, format = "csv2") expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, format = "csv2"))) }) }) test_that("Export to and Import from TSV with CSV extension", { withr::with_tempfile("iris_file", fileext = ".csv", code = { export(iris, iris_file, format = "tsv") expect_true(file.exists(iris_file)) expect_true(ncol(import(iris_file)) == 5L) expect_true(ncol(import(iris_file, format = "tsv")) == 5L) expect_true(ncol(import(iris_file, format = "tsv", sep = "\t")) == 5L) expect_true(ncol(import(iris_file, sep = ",")) == 5L) # use `data.table::fread(sep = "auto")` even if `sep` set explicitly to "," expect_true(ncol(import(iris_file, format = "csv")) == 5L) expect_true(ncol(import(iris_file, sep = "auto")) == 5L) }) }) test_that("fread is deprecated", { withr::with_tempfile("iris_file", fileext = ".csv", code = { export(iris, iris_file) lifecycle::expect_deprecated(import(iris_file, fread = TRUE)) lifecycle::expect_deprecated(import(iris_file, fread = FALSE)) }) }) test_that("dat (ambiguous file format) will be attempted #430", { withr::with_tempfile("iris_file", fileext = ".dat", code = { readr::write_delim(iris, file = iris_file) expect_error(suppressMessages(import(iris_file)), NA) expect_message(z <- import(iris_file)) ## export is not supported though expect_error(export(iris, iris_file)) }) }) rio/tests/testthat/test_format_fst.R0000644000176200001440000000043414612465270017403 0ustar liggesusersskip_if_not_installed(pkg="fst") test_that("Export to and import from fst", { withr::with_tempfile("iris_file", fileext = ".fst", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) rio/tests/testthat/test_format_feather.R0000644000176200001440000000044214612465270020224 0ustar liggesusersskip_if_not_installed("arrow") test_that("Export to and import from feather", { withr::with_tempfile("iris_file", fileext = ".feather", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) rio/tests/testthat/test_format_csvy.R0000644000176200001440000000047514612465270017600 0ustar liggesuserstest_that("Export to and import from CSVY", { withr::with_tempfile("iris_file", fileext = ".csvy", code = { suppressWarnings(export(iris, iris_file)) expect_true(file.exists(export(iris, iris_file))) suppressWarnings(d <- import(iris_file)) expect_true(is.data.frame(d)) }) }) rio/tests/testthat/test_extensions.R0000644000176200001440000000135414612465270017440 0ustar liggesuserslibrary("datasets") test_that("S3 extension mechanism works for imports", { withr::with_tempdir({ 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", { withr::with_tempdir({ 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) }) }) rio/tests/testthat/test_format_R.R0000644000176200001440000000076714621337153017017 0ustar liggesusersrequire("datasets") test_that("Export / Import to .R dump file", { withr::with_tempfile("iris_file", fileext = ".R", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) }) withr::with_tempfile("iris_file", fileext = ".dump", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file, trust = TRUE))) }) }) rio/tests/testthat/test_format_arff.R0000644000176200001440000000037214612465270017526 0ustar liggesuserstest_that("Weka (.arff) imports/exports", { withr::with_tempfile("iris_file", fileext = ".arff", code = { export(iris, iris_file) expect_true(file.exists(iris_file)) expect_true(is.data.frame(import(iris_file))) }) }) rio/tests/testthat.R0000644000176200001440000000011314476051106014167 0ustar liggesuserslibrary("testthat") library("rio") test_check("rio", reporter = "summary") rio/tests/testdata/0000755000176200001440000000000014613732533014025 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/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/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/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/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/br-in-td.html0000644000176200001440000000024714476051106016327 0ustar liggesusers
RowSTUDYID
1
2
rio/tests/testdata/iris_no_extension_xls0000644000176200001440000005200014613732533020371 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/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/two-tbody.html0000644000176200001440000000024514476051106016641 0ustar liggesusers
DatasetDescription
COComments
rio/MD50000644000176200001440000001562414675043102011365 0ustar liggesusersd1d625d7be515bb610fd098f82533261 *DESCRIPTION 2d06dd09a058d719e1809fc3032d6ca4 *NAMESPACE 397465cd1a97690a5cfb9471f24fb338 *NEWS.md 57348ed683ea9ae7d0074d1148734984 *R/characterize.R 9bf5feab9a39544ae225e9dd9a0b6120 *R/compression.R 807ddc7d46c576546e3a1e74d634153a *R/convert.R 634654e354947176bc49f9d3c3182d8f *R/export.R c369fd56d212bb0a8d29aec912203536 *R/export_list.R bfeb93b09595d170d50fad9d8eb2b5e8 *R/export_methods.R dd05e3c9e43944585ef3491cbed9e604 *R/extensions.R 6ba19992e26f284ab6b459d0cbd058a1 *R/gather_attrs.R 747861450002e4c692737f07a537a9a8 *R/import.R bceb19b7b93dc04ee69c18f44c7b4682 *R/import_list.R e0b3e3579cd1f5341d35289fe8d7a3c6 *R/import_methods.R c448135d26966e044c0bce588136b800 *R/onLoad.R c83a328c2e2d3ccd7f833da05e0fc9ac *R/remote_to_local.R 6b08304fa953b829561d8a6e68eece74 *R/rio.R 32bb09715c44a18a3ce9f8609027daa0 *R/set_class.R 30006786c00caa54f5a167a85b7fbb5f *R/standardize_attributes.R 84e4c407a077cf6cce05b0a5fd343c88 *R/suggestions.R 6d3d9eb0bd201ba04d3b23b05639c0be *R/sysdata.rda 272f3b5530690d844e940d3e35966e69 *R/utils.R 15087a1cc12d26952951216080ea42cc *README.md 7b006ddbc0c79a66593e79faff37dee0 *build/vignette.rds 10d45832d34b09559c23c29362cad423 *inst/CITATION 5c30adebcb89825549d5609439609123 *inst/doc/extension.R de6ca8d3c9e38a95202c14292ac751d3 *inst/doc/extension.Rmd b64f6b55503c515566fe4b04f0970506 *inst/doc/extension.html f12bff071ab3f2dbac493065848f98d4 *inst/doc/labelled.R 8edce779bf5ec09051660d36fb752f4f *inst/doc/labelled.Rmd 870002226e0af303b8eef71cf738e4a6 *inst/doc/labelled.html ba75c9b6382514c0caa9a1d7a79aae6b *inst/doc/philosophy.Rmd 5a329bd9f880788e8adfb8f5f677a0dd *inst/doc/philosophy.html 35ca6504a4b6f07186d3419c087e4204 *inst/doc/remap.R 43610d2a5f4f895b656b06d0b584897a *inst/doc/remap.Rmd b04c81c4a6b181575684bc43634bae8e *inst/doc/remap.html f72022aadc5a55d95027f4e424a77196 *inst/doc/rio.R 3afc43de362e6015bc0c58295284ff76 *inst/doc/rio.Rmd e8b1a701c447b3995f11e82bc8aef245 *inst/doc/rio.html 83ac65fcc39b019e543625a644ef7c0d *man/characterize.Rd 2a8458a6c3e87a9730f950a6b515d8bd *man/convert.Rd b2cf00a278415d50c286f8118fb0a5cb *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 9a562e8f0cb497fb38555eeef556f5ab *man/import.Rd 1239df3655cead286b971cf49e7b382f *man/import_list.Rd 21388f2d00d30a9788fb1f43660d6737 *man/install_formats.Rd b926a1ec904eb6b679c8879804291d06 *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 408c5b85e5327e84302fe436e90c412e *tests/testdata/iris_no_extension_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 ea11381f66483422aca6f554bdeee27c *tests/testthat/test_check_file.R 68ba85c42ef30cbd7bbd80a95cedb822 *tests/testthat/test_compress.R 349a691d1a7d6966b2ba70468a20a096 *tests/testthat/test_convert.R 49af6144c1cd9b739d28dd49b49abcca *tests/testthat/test_create_outfiles.R 95129f3024c27e361e0b3e7e926fa37f *tests/testthat/test_errors.R dbfd64ea6c477c07dbd3b9814bd92de1 *tests/testthat/test_export_corner_cases.R 3c39e65c9f30c98c6e9de4d5467af8e9 *tests/testthat/test_export_list.R 2751b76ade9fe599e300f6f6b79ae2e6 *tests/testthat/test_extensions.R 016415bec5714d622429ca80c7b489e2 *tests/testthat/test_format_R.R e844736e4fc3a6a09d2b2b4781073922 *tests/testthat/test_format_arff.R 308cbf91868e92104b2ed10891190f76 *tests/testthat/test_format_csv.R 8fb8c6f70709247b11d28cabfbefd9a8 *tests/testthat/test_format_csvy.R 4204e1d40bdfc2ebe3c993f7e96638e3 *tests/testthat/test_format_dbf.R dca6136154d9b5bc30a43aa9f932e00d *tests/testthat/test_format_dif.R d28aaa193c432c056fdcf5bd100726a9 *tests/testthat/test_format_dta.R ddc113687e5126c08cf7e94486984934 *tests/testthat/test_format_eviews.R 5ae5678a5dc8b2c7159a33fb956df486 *tests/testthat/test_format_external_packages.R b3d9bd4766675c2cfa048da5afed8caf *tests/testthat/test_format_feather.R a5ea7e322af1ae10a531927892da9fb4 *tests/testthat/test_format_fortran.R f2c7de362c2afd96285076194ddcf3bf *tests/testthat/test_format_fst.R 80a4fdf08ce1380d9730b589204e2174 *tests/testthat/test_format_fwf.R 71b0b661a24097c9e92a890aad0cf6d3 *tests/testthat/test_format_html.R df7a3a9efeb1c3cca518d301ecb7f3cd *tests/testthat/test_format_json.R 3acbd18a7646d1f5b41c061a801c66c0 *tests/testthat/test_format_matlab.R a69fd46f4efa066a4bd410744dfdc76e *tests/testthat/test_format_mtp.R 5e32679128f1605b7432a4b4cb69d243 *tests/testthat/test_format_ods.R 1198c3342790b73637d64981a356900b *tests/testthat/test_format_parquet.R 8dada8e5bd64785ed4ab7da8e1b281a4 *tests/testthat/test_format_psv.R 0b248d0acfe15be566b9314be0f27068 *tests/testthat/test_format_pzfx.R 61f73c1cf1891b1e044b60927ad2e0dd *tests/testthat/test_format_qs.R 3cc5414d16eb3e5f9e407122fea3cbe8 *tests/testthat/test_format_rdata.R f4ed6c07f05eab86540c2777abb1bb91 *tests/testthat/test_format_rds.R 5262389e045800f6bf5dd15581baa3a9 *tests/testthat/test_format_rec.R 16a860da65b63db34ed701627f39e74c *tests/testthat/test_format_sas.R 426e38acc666b1317b905f5d20158ccb *tests/testthat/test_format_sav.R 87988f069bc5c3e48b83ef16b47466e3 *tests/testthat/test_format_syd.R bfbeb0c010d6a520dec98f1f6007645c *tests/testthat/test_format_tsv.R 63c3c462a11a107d6ab83d52c8b7349c *tests/testthat/test_format_xls.R c05ecc386758042bca55723980001f17 *tests/testthat/test_format_xml.R c3e427e18bada76974abb0a130a8c6e8 *tests/testthat/test_format_yml.R e69c7994bad4f7a2608e95eca857e057 *tests/testthat/test_gather_attrs.R c117cca3954826104b97143a431111ef *tests/testthat/test_guess.R 4c617e86362ae380f5611ea03bacbbc1 *tests/testthat/test_identical.R 369d326a534af1ed3e9c18758cadf3bc *tests/testthat/test_import_list.R 91bfd8127194819247fb5f7518ca55a8 *tests/testthat/test_mapping.R 0da386ed5df6a0b81c4d18738665db21 *tests/testthat/test_matrix.R 2b0f36eb8e3eb2e6dac1d5c4ac9dccf7 *tests/testthat/test_remote.R 867938025f8317102c23b6a7b891aeb0 *tests/testthat/test_set_class.R 1d7f6d1a2071ed30efcc7901e0642a50 *tests/testthat/test_suggestions.R 84636503bbbff2000a8fa26bf5db4820 *tests/testthat/test_trust.R de6ca8d3c9e38a95202c14292ac751d3 *vignettes/extension.Rmd 8edce779bf5ec09051660d36fb752f4f *vignettes/labelled.Rmd ba75c9b6382514c0caa9a1d7a79aae6b *vignettes/philosophy.Rmd 43610d2a5f4f895b656b06d0b584897a *vignettes/remap.Rmd 3afc43de362e6015bc0c58295284ff76 *vignettes/rio.Rmd 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] "" rio/R/0000755000176200001440000000000014675002347011254 5ustar liggesusersrio/R/export_list.R0000644000176200001440000000710014622741132013743 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) supported_archive_formats <- c("zip", "tar", "tar.gz", "tar.bz2") if (!is.na(archive_format$compress) && !archive_format$compress %in% supported_archive_formats) { stop("'archive' is specified but format is not supported. Only zip and tar formats are supported.", call. = FALSE) } if (inherits(x, "data.frame")) { stop("'x' must be a list. Perhaps you want export()?", call. = FALSE) } .check_tar_support(archive_format$compress, getRversion()) 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, type = archive_format$compress) unlink(outfiles_normalized) return(invisible(archive)) } return(invisible(outfiles)) } rio/R/gather_attrs.R0000644000176200001440000000503414643604515014070 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]]), fixed = TRUE))) { 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(lengths(varattrs))) { 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/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/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/import.R0000644000176200001440000003006014650123352012701 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 (can be Gzip or Bzip2 compressed), .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 an archive format (zip and tar), `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. But please see the section `which` below. 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()], see `trust` below. #' \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), see `trust` below. #' \item Serialized R objects (.rds), using [base::readRDS()]. This can be any R object (not just a data frame), see `trust` below. #' \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 [CSVY](https://github.com/csvy) (CSV with a YAML metadata header) using [data.table::fread()]. #' \item Apache Arrow Parquet (.parquet), using [nanoparquet::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. #' #' # Trust #' For serialization formats (.R, .RDS, and .RData), please note that you should only load these files from trusted sources. It is because these formats are not necessarily for storing rectangular data and can also be used to store many things, e.g. code. Importing these files could lead to arbitary code execution. Please read the security principles by the R Project (Plummer, 2024). When importing these files via `rio`, you should affirm that you trust these files, i.e. `trust = TRUE`. See example below. If this affirmation is missing, the current version assumes `trust` to be true for backward compatibility and a deprecation notice will be printed. In the next major release (2.0.0), you must explicitly affirm your trust when importing these files. #' #' # Which #' For compressed archives (zip and tar, where a compressed file can contain multiple files), it is possible to come to a situation where the parameter `which` is used twice to indicate two different concepts. For example, it is unclear for `.xlsx.zip`whether `which` refers to the selection of an exact file in the archive or the selection of an exact sheet in the decompressed Excel file. In these cases, `rio` assumes that `which` is only used for the selection of file. After the selection of file with `which`, `rio` will return the first item, e.g. the first sheet. #' #' Please note, however, `.gz` and `.bz2` (e.g. `.xlsx.gz`) are compressed, but not archive format. In those cases, `which` is used the same way as the non-compressed format, e.g. selection of sheet for Excel. #' #' @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. #' @references #' Plummer, M (2024). Statement on CVE-2024-27322. [https://blog.r-project.org/2024/05/10/statement-on-cve-2024-27322/](https://blog.r-project.org/2024/05/10/statement-on-cve-2024-27322/) #' @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") #' ## options(rio.import.class = "tibble"), or options(rio.import.class = "arrow") #' #' ## Security #' rds_file <- tempfile(fileext = ".rds") #' export(iris, rds_file) #' #' ## You should only import serialized formats from trusted sources #' ## In this case, you can trust it because it's generated by you. #' import(rds_file, trust = TRUE) #' @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) } ## compressed file, f is a pretty bad name; but export() uses it. f <- find_compress(file) if (!is.na(f$compress)) { cfile <- file file <- f$file which <- ifelse(missing(which), 1, which) file <- parse_archive(cfile, which = which, file_type = f$compress) format <- .get_compressed_format(cfile, file, f$compress, format) ## reset which if `file` is zip or tar. #412 which <- .reset_which(file_type = f$compress, which = which) } if (missing(format)) { format <- get_info(file)$format } else { ## format such as "|" format <- .standardize_format(format) } 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/set_class.R0000644000176200001440000000223114572340025013347 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 (nrow(out) == 0) { return(out) } if (!length(rownames(out))) { rownames(out) <- as.character(seq_len(length(out[, 1L, drop = TRUE]))) } return(out) } rio/R/import_list.R0000644000176200001440000001501114643604515013742 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, compressed directory in a zip file or tar archive, or HTML file) #' @param file A character string containing a single file name for a multi-object file (e.g., Excel workbook, zip file, tar archive, 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 #' @inheritSection import Trust #' @inheritSection import Which #' @inherit import references #' @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. #' @details When file is a vector of file paths and any files are missing, those files are ignored (with warnings) and this function will not raise any error. For compressed files, the file name must also contain information about the file format of all compressed files, e.g. `files.csv.zip` for this function to work. #' @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 value 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.", call. = FALSE) return(x) } x <- x2 } 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), call. = FALSE) ##out <- NULL return(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") { return(.import.rio_rdata(file = file, .return_everything = TRUE, ...)) } archive_format <- find_compress(file) if (!get_info(file)$format %in% c("html", "xlsx", "xls") && !archive_format$compress %in% c("zip", "tar", "tar.gz", "tar.bz2")) { 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 (archive_format$compress %in% c("zip", "tar", "tar.gz", "tar.bz2")) { whichnames <- .list_archive(file, archive_format$compress) if (missing(which)) { which <- seq_along(whichnames) names(which) <- .strip_exts(whichnames) } else if (is.character(which)) { whichnames <- whichnames[whichnames %in% which] } else { 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/extensions.R0000644000176200001440000000247614643604515013607 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 <- strsplit(fileinfo$import_function, "::", fixed = TRUE)[[1]][1] 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/rio.R0000644000176200001440000000322714622742360012172 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 #' [datamods](https://cran.r-project.org/package=datamods) provides Shiny modules for importing data via `rio`. #' #' [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/export_methods.R0000644000176200001440000002350314650123352014437 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( "\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") 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(nanoparquet::write_parquet, ..., args = list(x = x, file = file)) } #' @export .export.rio_qs <- function(file, x, ...) { .check_pkg_availability("qs") .docall(qs::qsave, ..., args = list(x = x, file = file)) } rio/R/suggestions.R0000644000176200001440000000446714675002347013764 0ustar liggesusers#' @title Install rio's \sQuote{Suggests} Dependencies #' @description Not all suggested packages are installed by default. These packages are not installed or loaded by default in order to create a slimmer and faster package build, install, and load. Use `show_unsupported_formats()` to check all unsupported formats. `install_formats()` installs all missing \sQuote{Suggests} dependencies for rio that expand its support to the full range of support import and export formats. #' @param \dots Additional arguments passed to [utils::install.packages()]. #' @return For `show_unsupported_formats()`, if there is any missing unsupported formats, it return TRUE invisibly; otherwise FALSE. For `install_formats()` it returns TRUE invisibly if the installation is succuessful; otherwise errors. #' @examples #' \donttest{ #' if (interactive()) { #' install_formats() #' } #' } #' @export install_formats <- function(...) { to_install <- uninstalled_formats() utils::install.packages(to_install, ...) invisible(TRUE) } uninstalled_formats <- function() { suggested_packages <- attr(rio_formats, "suggested_packages") ## which are not installed suggested_packages[!R.utils::isPackageInstalled(suggested_packages)] } #' @rdname install_formats #' @export show_unsupported_formats <- function() { ## default_formats <- sort(unique(rio_formats$format[rio_formats$type == "import"])) suggested_formats <- rio_formats[rio_formats$type == "suggest",] suggested_formats$pkg <- vapply(strsplit(suggested_formats$import_function, "::"), FUN = `[`, FUN.VALUE = character(1), 1) missing_pkgs <- uninstalled_formats() suggested_formats$installed <- vapply(suggested_formats$pkg, function(x) x %in% missing_pkgs, logical(1), USE.NAMES = FALSE) unsupported_formats <- suggested_formats[suggested_formats$installed,] if (nrow(unsupported_formats) == 0) { message("All default and optional formats are supported.") return(invisible(FALSE)) } temp_display <- unsupported_formats[,c("input", "format", "pkg")] colnames(temp_display)[3] <- "Suggested package" print(temp_display) message("These formats are not supported. If you need to use these formats, please either install the suggested packages individually, or install_formats() to install them all.") return(invisible(TRUE)) } rio/R/standardize_attributes.R0000644000176200001440000000376414643604515016167 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]]), fixed = TRUE))) { 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), fixed = TRUE))) { 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/R/utils.R0000644000176200001440000001321114672241272012534 0ustar liggesusers#' @title Get File Info #' @description A utility function to retrieve the file information of a filename, path, or URL. #' @param file A character string containing a filename, file path, or URL. #' @return For [get_info()], a list is return with the following slots #' \itemize{ #' \item `input` file extension or information used to identify the possible file format #' \item `format` file format, see `format` argument of [import()] #' \item `type` "import" (supported by default); "suggest" (supported by suggested packages, see [install_formats()]); "enhance" and "known " are not directly supported; `NA` is unsupported #' \item `format_name` name of the format #' \item `import_function` What function is used to import this file #' \item `export_function` What function is used to export this file #' \item `file` `file` #' } #' For [get_ext()], just `input` (usually file extension) is returned; retained for backward compatibility. #' @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") #' @export get_info <- function(file) { .check_file(file, single_only = TRUE) if (tolower(file) == "clipboard") { return(.query_format(input = "clipboard", file = "clipboard")) } if (isFALSE(R.utils::isUrl(file))) { ext <- tolower(tools::file_ext(file)) } else { parsed <- strsplit(strsplit(file, "?", fixed = TRUE)[[1]][1], "/", fixed = TRUE)[[1]] url_file <- parsed[length(parsed)] ext <- tolower(tools::file_ext(url_file)) } if (ext == "") { stop("'file' has no extension", call. = FALSE) } return(.query_format(input = ext, file = file)) } #' @export #' @rdname get_info get_ext <- function(file) { get_info(file)$input } .query_format <- function(input, file) { unique_rio_formats <- unique(rio_formats[, colnames(rio_formats) != "note"]) if (file == "clipboard") { output <- as.list(unique_rio_formats[unique_rio_formats$format == "clipboard", ]) output$file <- file return(output) } ## TODO google sheets matched_formats <- unique_rio_formats[unique_rio_formats$input == input, ] if (nrow(matched_formats) == 0) { return(list(input = input, format = NA, type = NA, format_name = NA, import_function = NA, export_function = NA, file = file)) } output <- as.list(matched_formats) output$file <- file return(output) } .standardize_format <- function(input) { info <- .query_format(input, "") if (is.na(info$format)) { return(input) } info$format } twrap <- function(value, tag) { paste0("<", tag, ">", 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) } if (any(is.na(file))) { stop("Invalid `file` argument: `file` must not be NA", 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 (!all(nzchar(names_x))) { 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) } .check_trust <- function(trust, format) { if (is.null(trust)) { warning("Missing `trust` will be set to FALSE by default for ", format, " in 2.0.0.", call. = FALSE) trust <- TRUE ## Change this for version 2.0.0 } if (isFALSE(trust)) { stop(format, " files may execute arbitary code. Only load ", format, " files that you personally generated or can trust the origin.", call. = FALSE) } NULL } .reset_which <- function(file_type, which) { ## see #412 if (file_type %in% c("zip", "tar", "tar.gz", "tar.bz2")) { return(1) } return(which) } rio/R/compression.R0000644000176200001440000001216414644264522013745 0ustar liggesusersfind_compress <- function(f) { if (endsWith(f, ".zip")) { return(list(file = sub("\\.zip$", "", f), compress = "zip")) } if (endsWith(f, ".tar.gz")) { return(list(file = sub("\\.tar\\.gz$", "", f), compress = "tar.gz")) } if (endsWith(f, ".tgz")) { return(list(file = sub("\\.tgz$", "", f), compress = "tar.gz")) } if (endsWith(f, ".tar.bz2")) { return(list(file = sub("\\.tar\\.bz2$", "", f), compress = "tar.bz2")) } if (endsWith(f, ".tbz2")) { return(list(file = sub("\\.tbz2$", "", f), compress = "tar.bz2")) } if (endsWith(f, ".tar")) { return(list(file = sub("\\.tar$", "", f), compress = "tar")) } if (endsWith(f, ".gzip")) { ## weird return(list(file = sub("\\.gzip$", "", f), compress = "gzip")) } if (endsWith(f, ".gz")) { return(list(file = sub("\\.gz$", "", f), compress = "gzip")) } if (endsWith(f, ".bz2")) { return(list(file = sub("\\.bz2$", "", f), compress = "bzip2")) } if (endsWith(f, ".bzip2")) { ## weird return(list(file = sub("\\.bzip2$", "", f), compress = "bzip2")) } return(list(file = f, compress = NA_character_)) } compress_out <- function(cfile, filename, type = c("zip", "tar", "tar.gz", "tar.bz2", "gzip", "bzip2")) { type <- ext <- match.arg(type) cfile2 <- basename(cfile) filename <- normalizePath(filename) if (type %in% c("gzip", "bzip2")) { return(.compress_rutils(filename, cfile, ext = ext)) } 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) ## for security, see #438 and #319 setwd(tmp) if (type == "zip") { o <- utils::zip(cfile2, files = basename(filename)) } if (type == "tar") { o <- utils::tar(cfile2, files = basename(filename), compression = "none") } if (type == "tar.gz") { o <- utils::tar(cfile2, files = basename(filename), compression = "gzip") } if (type == "tar.bz2") { o <- utils::tar(cfile2, files = basename(filename), compression = "bzip2") } setwd(wd) ## see #438 if (o != 0) { stop(sprintf("File compression failed for %s!", cfile)) } file.copy(from = file.path(tmp, cfile2), to = cfile, overwrite = TRUE) return(cfile) } parse_archive <- function(file, which, file_type, ...) { if (file_type %in% c("gzip", "bzip2")) { ## it doesn't have the same interface as unzip return(.parse_rutils(filename = file, file_type = file_type)) } if (file_type == "zip") { extract_func <- utils::unzip } if (file_type %in% c("tar", "tar.gz", "tar.bz2")) { extract_func <- utils::untar } file_list <- .list_archive(file, file_type) d <- tempfile() dir.create(d) 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)) } .list_archive <- function(file, file_type = c("zip", "tar", "tar.gz", "tar.bz2")) { ## just a simple wrapper to unify the interface of utils::unzip and utils::untar file_type <- match.arg(file_type) if (file_type == "zip") { file_list <- utils::unzip(file, list = TRUE)$Name } if (file_type %in% c("tar", "tar.gz", "tar.bz2")) { file_list <- utils::untar(file, list = TRUE) } return(file_list) } .compress_rutils <- function(filename, cfile, ext, remove = TRUE, FUN = gzfile) { ## Caution: Please note that remove = TRUE by default, it will delete `filename`! if (ext == "bzip2") { FUN <- bzfile } tmp_cfile <- R.utils::compressFile(filename = filename, destname = tempfile(), ext = ext, FUN = FUN, overwrite = TRUE, remove = remove) file.copy(from = tmp_cfile, to = cfile, overwrite = TRUE) unlink(tmp_cfile) return(cfile) } .parse_rutils <- function(filename, file_type) { if (file_type == "gzip") { decompression_fun <- gzfile } if (file_type == "bzip2") { decompression_fun <- bzfile } destname <- tempfile() R.utils::decompressFile(filename = filename, destname = destname, temporary = TRUE, remove = FALSE, overwrite = TRUE, FUN = decompression_fun, ext = file_type) } .check_tar_support <- function(file_type, rversion) { if (file_type %in% c("tar", "tar.gz", "tar.bz2") && rversion < "4.0.3") { stop("Exporting to tar formats is not supported for this version of R.", call. = FALSE) } NULL } .get_compressed_format <- function(cfile, file, file_type, format) { if (file_type %in% c("gzip", "bzip2")) { return(ifelse(isFALSE(missing(format)), tolower(format), get_info(find_compress(cfile)$file)$input)) } ## zip or tar formats, use the decompressed file path return(ifelse(isFALSE(missing(format)), tolower(format), get_info(file)$input)) } rio/R/sysdata.rda0000644000176200001440000000450314650747025013420 0ustar liggesusersBZh91AY&SYG/z o?@` ?}{>)6lN:z88I"bi=2dyMF4GM1=&dhyOPO41OTO(dFA 4$)x4 @ '#&TD&f(hhRG @d  QOiƣ'C?EK!|\VLB|@c"$ T/2>`KEXoU u쐀@,WՌ1UJۍP?='!DEb-Qt(G&̧]I It8NULwDD&DB?b\pxY [o3 ? 쥙akFhȨ2U9њTQK{-*9 46cD ,XAjEP ]΁aZƎ덃ʌrV';]6;f TJ-nfMI΀ҐyR pV ID$T[^uM% YX.8ĉ }:2W*Q+(A*@!!E ,`,D BA`"XR dER`H!CH4 Yn{l~R'5cy*kvYW$A lNWprSk=~,ZC$eE!}TisdqW"A`HujNr6*z*!`XR,Mf,j3ՓYAC3* eK詣") 6)ETW|qz {B 0EkX0O^1lvu^8 Jg4ra C;1C7?7 K*Y@C*Tc5:m[DMd,U(jny˃WG)Hw{qNG((<:J(+-S3ZZ'4k,{FGTxcQD%c5k\L> 3 rZcuk=dڃ$;D ,+l`%HҢEhZ}KELI*I", ˺&JAdnưSPHM 0BO>a&2 /PGJP.~ S!Q5eT4E R$à5!ͤW5'ϋ>(p# S%RE1 $@"UK1"/8l<Up#nUμƔkMo*qr3o#riByE1)4(RZ)TEBR D$@PϜE@Xſ`b!n4pH,<-f6WXCt0K1X&\1EDU&r NWy"ٌO95ILd%En( Ll˾tkm0 GHPBPyt2Ŝc}l r$o)U&"EMm)'>͂]9*:Xoz J`QJhR*ڍ,av_%0XQQ܉Ԃ"YL*m ԕ $Ɛg%eJ8MHL%$llWF%Lc3PW65Bv\[VcU&9>mh\}d&?f2ҤB6i0IXͪ lnb 4;kw+FJrW^s Q)4=^ڦ2]ʆwm|پ6,ƙKq:-%2dؗ&N2,pMz[T bzp4 'y-lV1 <#@4M.)gl2jKxPѢI0.E:f+xJL#rBM' xNrY2|Ⱥm9^2 c@ʙG ݿa Rnc9Y9N;[Z "J*ũjq+TXQnkme.pŊ1jHjms4 cQCvH4 ׯTdb7%; Wh4ajFmc 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, trust = getOption("rio.import.trust", default = NULL), ...) { .check_trust(trust, format = "RDS") readRDS(file = file) } #' @export .import.rio_rdata <- function(file, which = 1, envir = new.env(), trust = getOption("rio.import.trust", default = NULL), .return_everything = FALSE, ...) { .check_trust(trust, format = "RData") load(file = file, envir = envir) if (isTRUE(.return_everything)) { ## for import_list() return(as.list(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, utils::type.convert) } else { d[] <- lapply(d, tc2) } 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 <- lengths(lapply(to_extract, unlist)) 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("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) == "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("nanoparquet") .docall(nanoparquet::read_parquet, ..., args = list(file = file, options = nanoparquet::parquet_options(class = "data.frame"))) } #' @export .import.rio_qs <- function(file, which = 1, ...) { .check_pkg_availability("qs") .docall(qs::qread, ..., args = list(file = file)) } rio/R/remote_to_local.R0000644000176200001440000000520614643604515014551 0ustar liggesusersremote_to_local <- function(file, format) { if (grepl("docs.google.com/spreadsheets", file, fixed = TRUE)) { if (missing(format) || (!missing(format) && !format %in% c("csv", "tsv", "xlsx", "ods"))) { format <- "csv" } file <- .convert_google_url(file, export_as = format) } if (missing(format)) { ## try to extract format from URL, see below format <- .get_ext_temp(file) } 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") { ## the happiest path return(temp_file) } ## fomart = "TMP": try to extract format from curl's final URL format <- .get_ext_temp(u$url) if (format != "TMP") { ## contain a file extension, also happy renamed_file <- sub("TMP$", format, temp_file) file.copy(from = temp_file, to = renamed_file) unlink(temp_file) return(renamed_file) } ## try to extract format from headers: read #403 about whether this code is doing anything h1 <- curl::parse_headers(u$headers) ## check `Content-Disposition` header if (!any(grepl("^Content-Disposition", h1))) { stop("Unrecognized file format. Try specifying with the format argument.") } h <- h1[grep("filename", h1, fixed = TRUE)] if (length(h)) { f <- regmatches(h, regexpr("(?<=\")(.*)(? %\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 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: ```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 == "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.dta") export(mtcars, "mtcars_noext", format = "csv") ``` ```{r} library("rio") x <- import("mtcars.csv") y <- import("mtcars.dta") # confirm identical all.equal(x, y, 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.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.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") ``` 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.dta") unlink("multi.xlsx") unlink("mtcars2.dta") unlink("mtcars.tsv") unlink("iris.tsv") ``` rio/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/philosophy.Rmd0000644000176200001440000001011714523367607015732 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 [**writexl**](https://cran.r-project.org/package=writexl) 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/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.Rmd0000644000176200001440000000430614643566357014651 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. `options(rio.ignoreunusedargs = FALSE)`. ```r options(rio.ignoreunusedargs = FALSE) import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") ``` ```{r map5, error = TRUE, echo = FALSE, purl = 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/NAMESPACE0000644000176200001440000000461714675002362012277 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(show_unsupported_formats) export(spread_attrs) rio/NEWS.md0000644000176200001440000006163014675007041012153 0ustar liggesusers# rio 1.2.3 * Fix #453, don't nudge the user to install all suggested packages * Fix #451, don't nudge the user to report issues about the trust parameter # rio 1.2.2 * Fix #447 - remove an ancient artefact of Vignette generation, h/t Tim Taylor for the help. # rio 1.2.1 * Roll back the decision to add parquet in the import tier see #455 #315 # rio 1.2.0 * Fix lintr issues #434 (h/t @bisaloo Hugo Gruson) * Drop support for R < 4.0.0 see #436 * Add support for parquet in the import tier using `nanoparquet` see rio 1.0.1 below. Bug fixes * Fix #430 Add back support for `.dat` # rio 1.1.1 Bug fixes * Fix #425 for archive formats, the file extension of the input file is determined by the compressed file (like prior rio 1.1.0) # rio 1.1.0 * CRAN release # rio 1.0.3 * Add `trust` parameter to functions that are used to load various R environment formats (`.R`, `.Rds`, `.Rdata`, etc). This parameter is defaulted to `TRUE` today to ensure backwards compatibility. A deprecation notice warns this will default to `FALSE` in `rio` 2.0. We are informing users that these data types should only be loaded from trusted sources, which should be affirmatively attested to. * Test and fix the compression mechanism: Gzip, Bzip2 are now working as expected. Bug fixes - Fix #412, prevent double usage of `which` for archive formats - Fix #415, both `import_list()` and `export_list()` support tar archives. - Fix #421, tar export is only supported by R >= 4.0.3. # rio 1.0.2 * For missing files in `import_list` it gives more informative warnings fix #389 * Single-item list of data frames can be exported fix #385 * Move `stringi` to Suggests to reduce compilation time. Add an attribution to the internal data to list out all required packages #378 * Move `readr` to Imports for `fwf`. `readr` is a dependency of `haven` so it does not increase the number of dependencies. Remove the original `read.fwf2` which doesn't guess `widths`. Keep the `widths` and `col.names` to maintain compatibility. #381 * Add (back) a pkgdown website: [https://gesistsa.github.io/rio/](https://gesistsa.github.io/rio/) * Update all test cases #380 # 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/inst/0000755000176200001440000000000014675017242012030 5ustar liggesusersrio/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/inst/doc/0000755000176200001440000000000014675017242012575 5ustar liggesusersrio/inst/doc/rio.Rmd0000644000176200001440000002302314660573663014042 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 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: ```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 == "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.dta") export(mtcars, "mtcars_noext", format = "csv") ``` ```{r} library("rio") x <- import("mtcars.csv") y <- import("mtcars.dta") # confirm identical all.equal(x, y, 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.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.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") ``` 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.dta") unlink("multi.xlsx") unlink("mtcars2.dta") unlink("mtcars.tsv") unlink("iris.tsv") ``` rio/inst/doc/extension.html0000644000176200001440000003600314675017240015477 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/doc/philosophy.html0000644000176200001440000003546414675017241015674 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 writexl 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/remap.R0000644000176200001440000000160614675017241014026 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") ## ----echo = FALSE, results = 'hide'------------------------------------------- unlink("example.xlsx") rio/inst/doc/extension.Rmd0000644000176200001440000000473014500415343015250 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/inst/doc/remap.html0000644000176200001440000006523314675017241014577 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. options(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.R0000644000176200001440000000220414675017241014461 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.R0000644000176200001440000000723714675017242013522 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 == "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.dta") export(mtcars, "mtcars_noext", format = "csv") ## ----------------------------------------------------------------------------- library("rio") x <- import("mtcars.csv") y <- import("mtcars.dta") # confirm identical all.equal(x, y, check.attributes = FALSE) ## ----------------------------------------------------------------------------- head(import("mtcars_noext", format = "csv")) ## ----echo=FALSE, results='hide'----------------------------------------------- unlink("mtcars.csv") unlink("mtcars.dta") unlink("mtcars_noext") ## ----------------------------------------------------------------------------- library("rio") export(mtcars, "mtcars.csv") 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_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.dta") unlink("multi.xlsx") unlink("mtcars2.dta") unlink("mtcars.tsv") unlink("iris.tsv") rio/inst/doc/philosophy.Rmd0000644000176200001440000001011714523367607015444 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 [**writexl**](https://cran.r-project.org/package=writexl) 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/inst/doc/labelled.Rmd0000644000176200001440000000247614500527537015016 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/inst/doc/rio.html0000644000176200001440000344120514675017242014265 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) tar / tar.gz / tgz / tar.bz2 / tbz2 utils utils Default
Bzip2 bz2 / bzip2 base base Default
Gzip gz / gzip base base Default
Zip files zip utils utils Default
Ambiguous file format dat data.table Default Attempt as delimited text data
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 readr 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 nanoparquet nanoparquet 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.dta")

# confirm identical
all.equal(x, y, 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.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")

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)))
## Warning: The `widths` argument of `import()` is deprecated as of rio 1.0.2.
## ℹ `widths` is kept for backward compatibility. Please use `col_positions` or
##   unset `widths` to allow automatic guessing, see `?readr::read_fwf`. The
##   parameter `widths` will be dropped in v2.0.0.
## ℹ The deprecated feature was likely used in the rio package.
##   Please report the issue at <https://github.com/gesistsa/rio/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Rows: 2 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## 
## dbl (3): X1, X2, X3
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## Rows: 2 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## 
## dbl (3): X1, X2, X3
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## [1] FALSE
# convert to CSV
convert(fwf, "fwf.csv", in_opts = list(widths = c(1, 2, 3)))
## Rows: 2 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## 
## dbl (3): X1, X2, X3
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
import("fwf.csv") # check conversion
##   X1 X2  X3
## 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.Rmd0000644000176200001440000000430614643566357014363 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. `options(rio.ignoreunusedargs = FALSE)`. ```r options(rio.ignoreunusedargs = FALSE) import("example.xlsx", sheet = "iris", n_max = 10, pizza = "pineapple") ``` ```{r map5, error = TRUE, echo = FALSE, purl = 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/inst/doc/extension.R0000644000176200001440000000035614675017240014736 0ustar liggesusers## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(rio) rio/inst/doc/labelled.html0000644000176200001440000004254314675017241015236 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  5 3 1 2 4
#>   ..- 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  5 3 1 2 4
#>   ..- 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/README.md0000644000176200001440000003430314674546115012342 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 ### 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 archives (e.g., zip), 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. You can check which formats are **not** supported via: ``` r show_unsupported_formats() ``` You can install the suggested packages individually, depending your own needs. If you want to install all suggested packages: ``` 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) | tar / tar.gz / tgz / tar.bz2 / tbz2 | utils | utils | Default | | | Bzip2 | bz2 / bzip2 | base | base | Default | | | Gzip | gz / gzip | base | base | Default | | | Zip files | zip | utils | utils | Default | | | Ambiguous file format | dat | data.table | | Default | Attempt as delimited text data | | 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 | readr | 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 | nanoparquet | nanoparquet | 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 - [**datamods**](https://cran.r-project.org/package=datamods) provides Shiny modules for importing data via `rio`. - [**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/build/0000755000176200001440000000000014675017242012152 5ustar liggesusersrio/build/vignette.rds0000644000176200001440000000052114675017242014507 0ustar liggesusersR=O0u> - &o+J*jXu6 Hsbn&|{w!8Pa`OM D9yæeƸP̎:4' $uءY{ ||` ;NMl݆$xӒۓ!.M5)R✕){zTh)ҏD0,=9w=F :Cjg Նz !$-.atDںk{%<{3=VBB|I4Z8_`Nw:r|Żz~~F`rio/man/0000755000176200001440000000000014674546115011633 5ustar liggesusersrio/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/export.Rd0000644000176200001440000001624614675002444013445 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, matrix or a single-item list of data frame to be written into a file. Exceptions to this rule are that \code{x} can be a list of multiple 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 \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[nanoparquet:write_parquet]{nanoparquet::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/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/rio.Rd0000644000176200001440000000632414650123352012704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rio.R \docType{package} \name{rio} \alias{rio-package} \alias{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. \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://cran.r-project.org/package=datamods}{datamods} provides Shiny modules for importing data via \code{rio}. \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] \item Hugo Gruson (\href{https://orcid.org/0000-0002-4094-1476}{ORCID}) [contributor] } } rio/man/import_list.Rd0000644000176200001440000001213314622630120014446 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, tar archive, 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, compressed directory in a zip file or tar archive, or HTML file) } \details{ When file is a vector of file paths and any files are missing, those files are ignored (with warnings) and this function will not raise any error. For compressed files, the file name must also contain information about the file format of all compressed files, e.g. \code{files.csv.zip} for this function to work. } \section{Trust}{ For serialization formats (.R, .RDS, and .RData), please note that you should only load these files from trusted sources. It is because these formats are not necessarily for storing rectangular data and can also be used to store many things, e.g. code. Importing these files could lead to arbitary code execution. Please read the security principles by the R Project (Plummer, 2024). When importing these files via \code{rio}, you should affirm that you trust these files, i.e. \code{trust = TRUE}. See example below. If this affirmation is missing, the current version assumes \code{trust} to be true for backward compatibility and a deprecation notice will be printed. In the next major release (2.0.0), you must explicitly affirm your trust when importing these files. } \section{Which}{ For compressed archives (zip and tar, where a compressed file can contain multiple files), it is possible to come to a situation where the parameter \code{which} is used twice to indicate two different concepts. For example, it is unclear for \code{.xlsx.zip}whether \code{which} refers to the selection of an exact file in the archive or the selection of an exact sheet in the decompressed Excel file. In these cases, \code{rio} assumes that \code{which} is only used for the selection of file. After the selection of file with \code{which}, \code{rio} will return the first item, e.g. the first sheet. Please note, however, \code{.gz} and \code{.bz2} (e.g. \code{.xlsx.gz}) are compressed, but not archive format. In those cases, \code{which} is used the same way as the non-compressed format, e.g. selection of sheet for Excel. } \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 value is a data frame import_list(xlsx_file, rbind = TRUE) } \references{ Plummer, M (2024). Statement on CVE-2024-27322. \url{https://blog.r-project.org/2024/05/10/statement-on-cve-2024-27322/} } \seealso{ \code{\link[=import]{import()}}, \code{\link[=export_list]{export_list()}}, \code{\link[=export]{export()}} } rio/man/figures/0000755000176200001440000000000014500616167013270 5ustar liggesusersrio/man/figures/logo.svg0000644000176200001440000106143714500615133014755 0ustar liggesusers image/svg+xml RIO rio/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/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/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/import.Rd0000644000176200001440000002734514675002444013440 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 (can be Gzip or Bzip2 compressed), .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 an archive format (zip and tar), \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. But please see the section \code{which} below. 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()}}, see \code{trust} below. \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), see \code{trust} below. \item Serialized R objects (.rds), using \code{\link[base:readRDS]{base::readRDS()}}. This can be any R object (not just a data frame), see \code{trust} below. \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 \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[nanoparquet:read_parquet]{nanoparquet::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. } \section{Trust}{ For serialization formats (.R, .RDS, and .RData), please note that you should only load these files from trusted sources. It is because these formats are not necessarily for storing rectangular data and can also be used to store many things, e.g. code. Importing these files could lead to arbitary code execution. Please read the security principles by the R Project (Plummer, 2024). When importing these files via \code{rio}, you should affirm that you trust these files, i.e. \code{trust = TRUE}. See example below. If this affirmation is missing, the current version assumes \code{trust} to be true for backward compatibility and a deprecation notice will be printed. In the next major release (2.0.0), you must explicitly affirm your trust when importing these files. } \section{Which}{ For compressed archives (zip and tar, where a compressed file can contain multiple files), it is possible to come to a situation where the parameter \code{which} is used twice to indicate two different concepts. For example, it is unclear for \code{.xlsx.zip}whether \code{which} refers to the selection of an exact file in the archive or the selection of an exact sheet in the decompressed Excel file. In these cases, \code{rio} assumes that \code{which} is only used for the selection of file. After the selection of file with \code{which}, \code{rio} will return the first item, e.g. the first sheet. Please note, however, \code{.gz} and \code{.bz2} (e.g. \code{.xlsx.gz}) are compressed, but not archive format. In those cases, \code{which} is used the same way as the non-compressed format, e.g. selection of sheet for Excel. } \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") ## options(rio.import.class = "tibble"), or options(rio.import.class = "arrow") ## Security rds_file <- tempfile(fileext = ".rds") export(iris, rds_file) ## You should only import serialized formats from trusted sources ## In this case, you can trust it because it's generated by you. import(rds_file, trust = TRUE) } \references{ Plummer, M (2024). Statement on CVE-2024-27322. \url{https://blog.r-project.org/2024/05/10/statement-on-cve-2024-27322/} } \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/install_formats.Rd0000644000176200001440000000220714674546115015324 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/suggestions.R \name{install_formats} \alias{install_formats} \alias{show_unsupported_formats} \title{Install rio's \sQuote{Suggests} Dependencies} \usage{ install_formats(...) show_unsupported_formats() } \arguments{ \item{\dots}{Additional arguments passed to \code{\link[utils:install.packages]{utils::install.packages()}}.} } \value{ For \code{show_unsupported_formats()}, if there is any missing unsupported formats, it return TRUE invisibly; otherwise FALSE. For \code{install_formats()} it returns TRUE invisibly if the installation is succuessful; otherwise errors. } \description{ Not all suggested packages are installed by default. These packages are not installed or loaded by default in order to create a slimmer and faster package build, install, and load. Use \code{show_unsupported_formats()} to check all unsupported formats. \code{install_formats()} installs all missing \sQuote{Suggests} dependencies for rio that expand its support to the full range of support import and export formats. } \examples{ \donttest{ if (interactive()) { install_formats() } } } 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/DESCRIPTION0000644000176200001440000000747214675043102012565 0ustar liggesusersPackage: rio Type: Package Title: A Swiss-Army Knife for Data I/O Version: 1.2.3 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")), person("Hugo", "Gruson", role = "ctb", comment = c(ORCID = "0000-0002-4094-1476")) ) Description: Streamlined data import and export by making assumptions that the user is probably willing to make: 'import()' and 'export()' determine the data format from the file extension, reasonable defaults are used for data import and export, web-based import is natively supported (including from SSL/HTTPS), compressed files can be read directly, and fast import packages are used where appropriate. An additional convenience function, 'convert()', provides a simple method for converting between file types. URL: https://gesistsa.github.io/rio/, https://github.com/gesistsa/rio BugReports: https://github.com/gesistsa/rio/issues Depends: R (>= 4.0) Imports: tools, stats, utils, foreign, haven (>= 1.1.2), curl (>= 0.6), data.table (>= 1.11.2), readxl (>= 0.1.1), tibble, writexl, lifecycle, R.utils, readr Suggests: datasets, bit64, testthat, knitr, magrittr, clipr, fst, hexView, jsonlite, pzfx, readODS (>= 2.1.0), rmarkdown, rmatio, xml2 (>= 1.2.0), yaml, qs, arrow (>= 0.17.0), stringi, withr, nanoparquet License: GPL-2 VignetteBuilder: knitr Encoding: UTF-8 RoxygenNote: 7.3.1 Config/Needs/website: gesistsa/tsatemplate NeedsCompilation: no Packaged: 2024-09-25 14:30:58 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] (), Hugo Gruson [ctb] () Maintainer: Chung-hong Chan Repository: CRAN Date/Publication: 2024-09-25 17:20:02 UTC