►1.2.1 Data
On this page:
1.2.1.1 Named data

1.2.1 Data🔗ℹ

Every fit, path and cross-validation procedure, and predict, takes its data in one of two ways: unnamed or named.

Unnamed data is the predictors, one row per observation and one column per predictor, with a separate response. The predictors are a math/matrix matrix, a list or vector of rows, each a list or vector, or a design matrix:

> (require math/matrix)
> (define X (matrix [[1.0 2.0] [2.0 1.0] [3.0 4.0] [4.0 3.0] [5.0 6.0]]))
> (define y '(1.2 3.9 3.1 5.8 5.1))
> (coef (ols X y))

'#(1.0816789548566557 1.8283186667839906 -0.858323423502696)

> (equal? (ols X y) (ols (matrix->list* X) y))

#t

A design matrix is a design-matrix? value: the predictors in the layout the solver reads, which every procedure converts its data to. Converting once yourself checks the data once, for many fits (see The explicit route).

The response has one entry per row: a list, a vector, an flvector, an f64vector, a math/array array or a Polars series. Its entries depend on the family:

Family

  

Response

Gaussian

  

reals

Binomial

  

0/1, or two class labels: strings, symbols or booleans

Multinomial

  

class numbers 0, …, K−1, every class present, or class labels

Cox

  

positive times and, separately, 0/1 or boolean event indicators

Poisson

  

non-negative counts

Multi-response Gaussian

  

a matrix with one column per response, in any form of unnamed data

Data is checked before the solver runs. Every numeric entry must be a finite real, every row the same length, and the response one entry per row; an error names the row and the column. R’s glmnet stops on a missing value too, but fits some infinite ones; here each is an error:

> (ols (matrix [[1.0 2.0] [2.0 +nan.0] [3.0 4.0]]) '(1 4 3))

ols: X has an element that is not finite

  column: 1

  row: 1

  element: +nan.0

> (ols X '(1.0 2.0))

ols: y does not have one entry per row of X

  length of y: 2

  rows of X: 5

  columns of X: 2

  hint: rows are observations; is X transposed?

Class labels are all text (strings or symbols) or all booleans:

> (logistic-fit X '(yes no "yes" #t no) #:lambda 0.1)

logistic-fit: contract violation

  expected: a string or a symbol, as the first element is

  given: #t

  in: the element at position 3 of

      the y argument of

      (->*

       (data/c

        (response-for/c

         X

         (or/c 0 1)

         #:classes?

         #t)

        #:lambda

        (>=/c 0))

       (#:predictors

        (predictors-for/c X y #:classes? #t)

        ...)

       logistic-result?)

  contract from: <pkgs>/glmnet/core/lognet.rkt

  blaming: program

   (assuming the contract is correct)

  at: <pkgs>/glmnet/core/lognet.rkt:33:3

1.2.1.1 Named data🔗ℹ

Named data is a table, an association list or a hash from column names to columns, or a Polars dataframe. The second argument names the response column, and #:predictors, then required, the predictor columns. No other column is read:

> (define patients
    '((age 34 51 67 45 29)
      (dose 2.5 5.0 1.0 3.5 4.0)
      (response 3.1 5.2 1.9 4.0 4.4)))
> (define by-name (ols patients "response" #:predictors '("age" "dose")))
> (coef by-name)

'#(1.037012353177952 0.0003874059523250326 0.8329615305552988)

> (predict by-name '((dose 3.0) (age 40)))

'(3.5513931829368497)

A fit from named data predicts from named data by column name, in any order. The Cox and multi-response families name several response columns (see Data arguments).

A formula, written with ~, names the response and the predictors in one expression, and keys the coefficients by name:

> (coef (formula-fit (~ response (+ age dose)) patients #:lambda 0.1))

'(("(Intercept)" . 1.2948504377976056)

  ("age" . 0.0)

  ("dose" . 0.7578592381882481))

Formulas and named data covers formulas, and Data where data comes from.