Skip to content

Commit

Permalink
[dims] fix overlapping column types. fixes #1023 (#1026)
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMarvin authored May 23, 2024
1 parent 2de13e4 commit dd94305
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 5 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

* Fixes to `wb_clone_worksheet()` cloning drawings and images should be restored. [1016](https://github.com/JanMarvin/openxlsx2/pull/1016)

* Fixed an issue where non consecutive columns with special types would overlap. If columns A and C were dates, column B would be formatted as date too. [1026](https://github.com/JanMarvin/openxlsx2/pull/1026)


***************************************************************************

Expand Down
42 changes: 42 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,48 @@ rowcol_to_dim <- function(row, col) {
# we will always return something like "A1"
stringi::stri_join(min_col, min_row)
}

#' consecutive range in vector
#' @param x integer vector
#' @keywords internal
con_rng <- function(x) {
if (length(x) == 0) return(NULL)
group <- cumsum(c(1, diff(x) != 1))

# Extract the first and last element of each group using tapply
ranges <- tapply(x, group, function(y) c(beg = y[1], end = y[length(y)]))
ranges_df <- do.call(rbind, ranges)

as.data.frame(ranges_df)
}

#' create consecutive dims from column and row vector
#' @param cols,rows integer vectors
#' @keywords internal
con_dims <- function(cols, rows) {

c_cols <- con_rng(cols)
c_rows <- con_rng(rows)

c_cols$beg <- int2col(c_cols$beg)
c_cols$end <- int2col(c_cols$end)

dims_cols <- paste0(c_cols$beg, "%s:", c_cols$end, "%s")

out <- NULL
for (i in seq_along(dims_cols)) {
for (j in seq_len(nrow(c_rows))) {
beg_row <- c_rows[j, "beg"]
end_row <- c_rows[j, "end"]

dims <- sprintf(dims_cols[i], beg_row, end_row)
out <- c(out, dims)
}
}

paste0(out, collapse = ",")
}

check_wb_dims_args <- function(args, select = NULL) {
select <- match.arg(select, c("x", "data", "col_names", "row_names"))

Expand Down
14 changes: 9 additions & 5 deletions R/wb_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,15 @@ dataframe_to_dims <- function(df, dim_break = FALSE) {
rows <- as.integer(rownames(df))
cols <- colnames(df)

tmp <- paste0(
cols[[1]][[1]], rows[[1]][[1]],
":",
rev(cols)[[1]][[1]], rev(rows)[[1]][[1]]
)
if (all(diff(col2int(cols)) == 1L) && all(diff(rows) == 1L)) {
tmp <- paste0(
cols[[1]][[1]], rows[[1]][[1]],
":",
rev(cols)[[1]][[1]], rev(rows)[[1]][[1]]
)
} else {
tmp <- con_dims(col2int(cols), rows)
}

return(tmp)

Expand Down
15 changes: 15 additions & 0 deletions man/con_dims.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions man/con_rng.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions tests/testthat/test-write.R
Original file line number Diff line number Diff line change
Expand Up @@ -1205,3 +1205,31 @@ test_that("writing zero row data frames works", {
expect_equal(exp, got)

})

test_that("non consecutive columns do not overlap", {
test_dt <- data.frame(
V1 = seq(as.Date("2024-01-01"), as.Date("2024-01-05"), 1),
V2 = letters[1:5],
V3 = seq(as.Date("2024-01-01"), as.Date("2024-01-05"), 1),
V4 = c(letters[3:5], NA, NA),
V5 = 1:5,
V6 = c(NA, NA, 3, 4, 5),
V7 = letters[1:5],
V8 = c(letters[3:5], NA, NA),
V9 = 1:5,
V0 = c(NA, NA, 3, 4, 5)
)

wb <- wb_workbook()$
add_worksheet()$
add_data(x = test_dt)

# df <- wb_to_df(wb, col_names = F)

cc <- wb$worksheets[[1]]$sheet_data$cc

exp <- ""
got <- cc[cc$r == "B2", "c_s"]
expect_equal(exp, got)

})

0 comments on commit dd94305

Please sign in to comment.