Skip to contents

Given the first several physical rows of a file (each a character vector, the file read so that NO row was consumed as a header), find which row is the real column header. Combines two signals, because no single one covers every file:

Usage

.detect_header_row(rows, max_scan = 4L)

Arguments

rows

a list of character vectors (one per physical row), all the same length; typically the first max_scan + 1 rows of a headerless read.

max_scan

how many leading rows to consider stripping as metadata.

Value

a list: header_row (1-based index of the true header, 1 = already correct / no offset), stripped (character vectors of the metadata rows above it), and improved (body type-consistency gained by the promotion).

Details

  1. Type-consistency of the body below. A text/banner/units row on top of numeric columns makes them look mixed; dropping it makes them cleanly numeric (see .numeric_col_fraction()). Strong when the data are numeric (the CDA/behavior sheets), weak when the body is mostly text.

  2. Junk rows above. A banner (one label repeated across columns) or a near-empty spacer row is not a header (see .is_junk_above_header()). This carries the cases where the numeric jump is weak – e.g. the CDA banner row of CDA x 110 sitting above a header that only relabels 3 of 113 columns.

The header is the SMALLEST h such that every row above h is junk, the body below h is type-consistent, and promoting h does not make the typing worse. When no leading row is junk, the header is row 1 (already correct).

Examples

rows <- list(c("Exported by lab software", ""), c("id", "rt"),
             c("1", "512"), c("2", "640"), c("3", "498"))
.detect_header_row(rows)$header_row
#> [1] 2