Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
on:
push:
branches:
- v1*
- v2*
pull_request:
branches:
- v1*
- v2*

name: R-CMD-check

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
on:
push:
branches:
- v1*
- v2*
pull_request:
branches:
- v1*
- v2*

name: test-coverage

Expand Down
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ Imports:
stringi,
utils,
zip,
tibble
tibble,
vctrs (>= 0.4.2)
LinkingTo:
cpp11
Suggests:
Expand Down
6 changes: 5 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ length(list_ods_sheets("starwars.ods"))
* `overwrite`: always TRUE
* `verbose`: always FALSE
* `na_as_string`: default to FALSE

*
## BREAKING CHANGES: read_ods now outputs as tibble by default
* Added `as_tibble` and `.name_repair` as arguments. If `as_tibble` is true, outputs as a tibble using `tibble::as_tibble()` passing on `.name_repair` (default being `"unique"`). **By default** `as_tibble` is set to TRUE.
* Removed `check_names` argument. All name repairs are now dealt with using `vctrs::vec_as_names()`. This will **significantly change** the default names given to outputs. (Names in the style of `check_names = TRUE` can be obtained by setting `.name_repair = minimal`, although this is not advised)

# readODS 1.9.0

* Added a `NEWS.md` file to track changes to the package.
Expand Down
67 changes: 30 additions & 37 deletions R/read_ods.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.change_df_with_col_row_header <- function(x, col_header, row_header) {
.change_df_with_col_row_header <- function(x, col_header, row_header, .name_repair) {
if((nrow(x) < 2 && col_header )|| (ncol(x) < 2 && row_header)) {
warning("Cannot make column/row names if this would cause the dataframe to be empty.", call. = FALSE)
return(x)
Expand All @@ -7,8 +7,15 @@
jcol <- ifelse(row_header, 2, 1)

g <- x[irow:nrow(x), jcol:ncol(x), drop=FALSE] # maintain as dataframe for single column


rownames(g) <- if(row_header) x[seq(irow, nrow(x)), 1] else NULL # don't want character row headers given by 1:nrow(g)
colnames(g) <- if(col_header) x[1, seq(jcol, ncol(x))] else cellranger::num_to_letter(seq_len(ncol(g)))
cols <- ncol(x)
if (row_header) {
cols <- cols - 1
}
col_n <- if(col_header) x[1, seq(jcol, ncol(x))] else c(rep("", cols))
colnames(g) <- vctrs::vec_as_names(unlist(col_n), repair = .name_repair)
return(g)
}

Expand Down Expand Up @@ -70,10 +77,8 @@
range = NULL,
row_names = FALSE,
strings_as_factors = FALSE,
check_names = FALSE,
verbose = FALSE,
as_tibble = FALSE,
.name_repair = "check_unique") {
as_tibble = TRUE) {
if (missing(path) || !is.character(path)) {
stop("No file path was provided for the 'path' argument. Please provide a path to a file to import.", call. = FALSE)
}
Expand All @@ -92,22 +97,14 @@
if (!is.logical(strings_as_factors)) {
stop("strings_as_factors must be of type `boolean`", call. = FALSE)
}
if (!is.logical(check_names)) {
stop("check_names must be of type `boolean`", call. = FALSE)
}
if (!is.logical(verbose)) {
stop("verbose must be of type `boolean`", call. = FALSE)
}
if (!is.logical(as_tibble)) {
stop("as_tibble must be of type `boolean", call. = FALSE)
}
if (as_tibble &&
(!(.name_repair %in% c("minimal",
"unique",
"check_unique",
"universal")) ||
is.function(.name_repair))) {
stop(".name_repair must either be one of \"minimal\", \"unique\", \"check_unique\", \"univseral\" or a function", call. = FALSE)
if (row_names && as_tibble){
stop("Tibbles do not support row names. To use row names, set as_tibble to false", call. = FALSE)
}
}

Expand All @@ -121,25 +118,22 @@
range = NULL,
row_names = FALSE,
strings_as_factors = FALSE,
check_names = FALSE,
verbose = FALSE,
as_tibble = FALSE,
.name_repair = "check_unique",
as_tibble = TRUE,
.name_repair = "unique",
flat = FALSE) {
.check_read_args(path,
sheet,
col_names,
col_types,
na,
skip,
skip,
formula_as_formula,
range,
row_names,
strings_as_factors,
check_names,
verbose,
as_tibble,
.name_repair)
as_tibble)
# Get cell range info
limits <- .standardise_limits(range, skip)
# Get sheet number.
Expand Down Expand Up @@ -194,16 +188,20 @@
}
if(strings[1] == 0 || strings[2] == 0) {
warning("empty sheet, return empty data frame.", call. = FALSE)
return(data.frame())
if(as_tibble){
return(tibble::tibble())
} else {
return(data.frame())
}
}
res <- as.data.frame(
matrix(
strings[-1:-2],
ncol = strtoi(strings[1]),
byrow = TRUE),
stringsAsFactors = FALSE)
res <- .change_df_with_col_row_header(res, col_names, row_names)
res <- data.frame(res, check.names = check_names)
res <- .change_df_with_col_row_header(res, col_names, row_names, .name_repair)
res <- data.frame(res)
if (inherits(col_types, 'col_spec')) {
res <- readr::type_convert(df = res, col_types = col_types, na = na)
} else if (length(col_types) == 0 && is.null(col_types)) {
Expand Down Expand Up @@ -243,19 +241,18 @@
#' @param range selection of rectangle using Excel-like cell range, such as \code{range = "D12:F15"} or \code{range = "R1C12:R6C15"}. Cell range processing is handled by the \code{\link[=cellranger]{cellranger}} package.
#' @param row_names logical, indicating whether the file contains the names of the rows as its first column. Default is FALSE.
#' @param strings_as_factors logical, if character columns to be converted to factors. Default is FALSE.
#' @param check_names logical, passed down to base::data.frame(). Default is FALSE.
#' @param verbose logical, if messages should be displayed. Default is FALSE.
#' @param as_tibble logical, if the output should be a tibble (as opposed to a data.frame). Default is FALSE.
#' @param as_tibble logical, if the output should be a tibble (as opposed to a data.frame). Default is TRUE.
#' @param .name_repair A string or function passed on as `.name_repair` to [tibble::as_tibble()]
#' - `"minimal"`: No name repair
#' - `"unique"` : Make sure names are unique and not empty
#' - `"check_unique"`: Check names are unique, but do not repair
#' - `"universal"` : Checks names are unique and valid R variables names in scope
#' - A function to apply custom name repair.
#'
#' Default is `"check_unique"`.
#' Default is `"unique"`.
#'
#' @return A data frame (\code{data.frame}) containing a representation of data in the (f)ods file.
#' @return A tibble (\code{tibble}) or data frame (\code{data.frame}) containing a representation of data in the (f)ods file.
#' @author Peter Brohan <peter.brohan+cran@@gmail.com>, Chung-hong Chan <chainsawtiney@@gmail.com>, Gerrit-Jan Schutten <phonixor@@gmail.com>
#' @examples
#' \dontrun{
Expand Down Expand Up @@ -283,10 +280,9 @@ read_ods <- function(path,
range = NULL,
row_names = FALSE,
strings_as_factors = FALSE,
check_names = FALSE,
verbose = FALSE,
as_tibble = FALSE,
.name_repair = "check_unique"
as_tibble = TRUE,
.name_repair = "unique"

) {
## Should use match.call but there's a weird bug if one of the variable names is 'file'
Expand All @@ -300,7 +296,6 @@ read_ods <- function(path,
range,
row_names,
strings_as_factors,
check_names,
verbose,
as_tibble,
.name_repair,
Expand All @@ -319,10 +314,9 @@ read_fods <- function(path,
range = NULL,
row_names = FALSE,
strings_as_factors = FALSE,
check_names = FALSE,
verbose = FALSE,
as_tibble = FALSE,
.name_repair = "check_unique"
as_tibble = TRUE,
.name_repair = "unique"

) {
## Should use match.call but there's a weird bug if one of the variable names is 'file'
Expand All @@ -336,7 +330,6 @@ read_fods <- function(path,
range,
row_names,
strings_as_factors,
check_names,
verbose,
as_tibble,
.name_repair,
Expand Down
7 changes: 5 additions & 2 deletions R/writeODS.R
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
}

## https://github.com/ropensci/readODS/issues/88
.vfwrite_ods <- function(x, temp_ods_dir, sheet = "Sheet1", row_names = FALSE, col_names = FALSE, na_as_string = FALSE) {
.vfwrite_ods <- function(x, temp_ods_dir, sheet = "Sheet1", row_names = FALSE, col_names = TRUE, na_as_string = FALSE) {
templatedir <- system.file("template", package = "readODS")
file.copy(dir(templatedir, full.names = TRUE), temp_ods_dir, recursive = TRUE, copy.mode = FALSE)
con <- file(file.path(temp_ods_dir, "content.xml"), open="w", encoding = "UTF-8")
Expand All @@ -121,7 +121,7 @@
#' @param append logical, TRUE indicates that x should be appended to the existing file (path) as a new sheet. If a sheet with the same sheet_name exists, an exception is thrown. See update. Please also note that writing is slower if TRUE. Default is FALSE.
#' @param update logical, TRUE indicates that the sheet with sheet_name in the existing file (path) should be updated with the content of x. If a sheet with sheet_name does not exist, an exception is thrown. Please also note that writing is slower if TRUE. Default is FALSE.
#' @param row_names logical, TRUE indicates that row names of x are to be included in the sheet. Default is FALSE.
#' @param col_names logical, TRUE indicates that column names of x are to be included in the sheet. Default is FALSE.
#' @param col_names logical, TRUE indicates that column names of x are to be included in the sheet. Default is TRUE.
#' @param na_as_string logical, TRUE indicates that NAs are written as string.
#' @return An ODS file written to the file path location specified by the user. The value of \code{path} is also returned invisibly.
#' @author Detlef Steuer <steuer@@hsu-hh.de>, Thomas J. Leeper <thosjleeper@@gmail.com>, John Foster <john.x.foster@@nab.com.au>, Chung-hong Chan <chainsawtiney@@gmail.com>
Expand All @@ -139,6 +139,9 @@ write_ods <- function(x, path, sheet = "Sheet1", append = FALSE, update = FALSE,
temp_ods_dir <- file.path(tempdir(), stringi::stri_rand_strings(1, 20, pattern = "[A-Za-z0-9]"))
dir.create(temp_ods_dir)
on.exit(unlink(temp_ods_dir))
if (inherits(x, "tbl_df")){ #Convert to a df if currently a tibble
x <- as.data.frame(x)
}
if (!is.data.frame(x)) {
stop("x must be a data.frame.", call. = FALSE)
}
Expand Down
4 changes: 2 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ Reading from a specific range
read_ods("starwars.ods", sheet = 2, range = "A1:C11")
```

Reading as a tibble
Reading as a dataframe
```{r}
read_ods("starwars.ods", range="Sheet1!A2:C11", as_tibble = TRUE)
read_ods("starwars.ods", range="Sheet1!A2:C11", as_tibble = FALSE)
```

#### Writing
Expand Down
Loading