Skip to content

Fix read.simple.ssv()/write.simple.xlsx() crashes and rewrite qs.2.table() - #31

Closed
vertesy wants to merge 2 commits into
mainfrom
fix/undefined-var-and-broken-qs2table
Closed

vertesy wants to merge 2 commits into
mainfrom
fix/undefined-var-and-broken-qs2table

Conversation

@vertesy

@vertesy vertesy commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the 3 bugs flagged during the recent code-annotation pass (#30), in R/ReadWriter.R.

Why

  • read.simple.ssv(): referenced asTibble, which wasn't a formal parameter of this function (its sibling read.simple.* functions already have it) — errored on any call with the default wRownames = TRUE. Added the missing parameter.
  • write.simple.xlsx(): its per-sheet assignRownames() helper used an external df instead of its own argument x — every sheet in a multi-sheet workbook was (re)built from the same data instead of its own.
  • qs.2.table(): non-functional on every branch — a single-colon qs:qread typo, a call to a non-existent stringi::stri_detect (stringi isn't even a declared dependency), and base_filename/out_path referenced without ever being defined. Rewrote it: reads the .qs file, then writes it out as tsv/csv/csv2/excel via the existing write.simple.tsv()/write.simple.xlsx() helpers (which derive the correct extension themselves), splitting path into directory + basename so manual_file_name never contains slashes.

Verified all 3 fixes interactively via devtools::load_all(), including a full round-trip of qs.2.table() across all 4 output formats and content-checking the written CSV. No tests/ directory exists in this repo.

read.simple.ssv() referenced `asTibble`, which wasn't a formal
parameter (its sibling read.* functions have it) -- added it back.
write.simple.xlsx()'s per-sheet assignRownames() helper used an
external `df` instead of its own argument `x`, so every sheet was
(re)built from the same data. qs.2.table() was non-functional on every
branch: a single-colon `qs:qread` typo, a call to a non-existent
`stringi::stri_detect`, and `base_filename`/`out_path` referenced
without ever being defined. Rewrote it to actually read a .qs file and
write it out as tsv/csv/csv2/excel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b20ae56be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread R/ReadWriter.R
# assign row names if required
if (isFALSE(has_row_names)) {
assignRownames <- function(x) column.2.row.names(df, rowname_column = rowname_column, make_names = TRUE)
assignRownames <- function(x) column.2.row.names(x, rowname_column = rowname_column, make_names = TRUE)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the converted row names in the workbook

When has_row_names = FALSE, this conversion removes rowname_column from every sheet and stores its values as row names, but the subsequent openxlsx::write.xlsx() call still uses rowNames = has_row_names and therefore omits those row names. The function now completes instead of crashing, but silently drops the identifier column from the resulting workbook; either write the converted row names or avoid removing the column.

Useful? React with 👍 / 👎.

Comment thread R/ReadWriter.R
Comment on lines 458 to +460
read.simple.ssv <- function(
..., sep_ = " ", colnames = TRUE, wRownames = TRUE, NaReplace = TRUE,
coltypes = NULL
coltypes = NULL, asTibble = FALSE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor asTibble when replacing missing values

With the newly exposed asTibble = TRUE and the default NaReplace = TRUE, line 467 immediately wraps the result in as.data.frame(), so the function returns a data frame rather than the advertised tibble. Callers only receive a tibble if they also disable NA replacement, an undocumented coupling that makes the new option ineffective under its normal defaults.

Useful? React with 👍 / 👎.

Comment thread R/ReadWriter.R
#' @param wRownames With row names? Default: TRUE.
#' @param NaReplace Replace NA values? Default: TRUE.
#' @param coltypes What type of variables are in columns? Auto-guessing can be very slow. Default: NULL.
#' @param asTibble Load as tibble or data frame? Default: FALSE (load as data frame).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Regenerate the Rd file after adding asTibble

The committed man/read.simple.ssv.Rd still shows the old signature ending at coltypes = NULL and contains no asTibble argument entry, so installed help disagrees with the exported function and users cannot discover the new option. Regenerate and commit the Rd output after changing the roxygen block and signature.

AGENTS.md reference: AGENTS.md:L21-L24

Useful? React with 👍 / 👎.

@vertesy

vertesy commented Aug 31, 2026

Copy link
Copy Markdown
Owner Author

@claude

Could you please address all of the issues that Codex code review has identified? Can you read the comments it has left in this PR? To prove that you can, please print me the first title row of all 3 issues raised.

@claude

claude Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

Claude finished @vertesy's task in 2m 7s —— View job


Done — all 3 Codex issues addressed

Todo list

  • Read Codex review comments on this PR
  • Fix P1: write.simple.xlsx() drops row names when has_row_names = FALSE (R/ReadWriter.R:961)
  • Fix P2: read.simple.ssv() ignores asTibble when NaReplace = TRUE (R/ReadWriter.R:460)
  • Fix P1: regenerate man/read.simple.ssv.Rd for the new asTibble param (R/ReadWriter.R:445)
  • Commit and push
  • Post summary

As proof I read the actual review comments, here are the first title rows of all 3 issues Codex raised:

  1. Preserve the converted row names in the workbook (P1, R/ReadWriter.R:961)
  2. Honor asTibble when replacing missing values (P2, R/ReadWriter.R:460)
  3. Regenerate the Rd file after adding asTibble (P1, R/ReadWriter.R:445)

What I changed (commit 73fe908)

  1. write.simple.xlsx() — after column.2.row.names() moves rowname_column out of each sheet's data and into row names, the function now sets has_row_names <- TRUE so the subsequent openxlsx::write.xlsx(..., rowNames = has_row_names) actually writes those row names instead of silently dropping the identifier column.
  2. read.simple.ssv() — NaReplace no longer unconditionally wraps the result in as.data.frame(). It now only does so when asTibble = FALSE, so passing asTibble = TRUE returns a tibble even under the default NaReplace = TRUE.
  3. man/read.simple.ssv.Rd — added the missing asTibble entry to \usage{} and \arguments{} so the Rd matches the new function signature/roxygen block. (Note: I couldn't run Rscript/devtools::document() in this sandbox — Bash execution required approval that wasn't available — so I hand-edited the Rd to exactly match what roxygen2 would generate from the existing @param asTibble doc comment. Worth a diff-check with devtools::document() locally to confirm.)

Not done: I did not touch the identical as.data.frame(gtools::na.replace(...)) pattern in the sibling functions read.simple.csv/read.simple.tsv (lines ~340, ~384) — they have the same latent bug, but Codex didn't flag them and they're outside this PR's diff, so I left them as-is per scope.

Branch: fix/undefined-var-and-broken-qs2table

- write.simple.xlsx(): flip has_row_names to TRUE after converting a
  column to row names, so openxlsx actually writes them instead of
  silently dropping the identifier column.
- read.simple.ssv(): only coerce to data.frame after NA-replacement
  when asTibble = FALSE, so asTibble is honored under the default
  NaReplace = TRUE.
- Regenerate man/read.simple.ssv.Rd for the new asTibble parameter.

Co-authored-by: Abel Vertesy <5101911+vertesy@users.noreply.github.com>
@vertesy

vertesy commented Aug 31, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #30, which now bundles the same fixes (plus an additional excel-branch fix).

@vertesy vertesy closed this Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant