1.4.1 Tables🔗ℹ

A table is any of these:

  • an association list of (name . column) pairs;

  • a hash from name to column;

  • a design-matrix? with column names.

A name is a string or a symbol, and a column a list, vector, flvector or f64vector of reals, or a list or vector of strings, symbols or booleans, which a formula reads as categories (see Categorical predictors). Names are compared as strings, so the symbol 'age and the string "age" name the same column.

The examples in this chapter use a table of 60 simulated patients, with three predictors, an "age", a "dose" and a "marker":

> (random-seed 1)
> (define (uniform a b) (+ a (* (- b a) (random))))
> (define n 60)
> (define age (for/list ([_ (in-range n)]) (+ 30 (random 51))))
> (define dose (for/list ([_ (in-range n)]) (uniform 0 10)))
> (define marker (for/list ([_ (in-range n)]) (uniform -1 1)))

The table also holds the responses of three models. Blood pressure, "bp", depends on age and dose, and a relapse, "relapse" (0 or 1), on dose and the marker:

> (define bp
    (for/list ([a (in-list age)] [d (in-list dose)])
      (+ 90 (* 0.6 a) (* -2 d) (uniform -5 5))))
> (define relapse
    (for/list ([d (in-list dose)] [m (in-list marker)])
      (if (> (+ 1 (* -0.4 d) (* 3 m) (uniform -1 1)) 0) 1 0)))

A survival time, "time", depends on age and the marker. It is the earlier of an event and a censoring time, and its indicator "status" is 1 where the event came first:

> (define event-times
    (for/list ([a (in-list age)] [m (in-list marker)])
      (/ (- (log (random))) (exp (+ (* 0.04 (- a 55)) (* 1.5 m))))))
> (define censor-times (for/list ([_ (in-range n)]) (uniform 0 4)))
> (define status
    (for/list ([e (in-list event-times)] [c (in-list censor-times)])
      (if (<= e c) 1 0)))

The table holds the columns by name:

> (define patients
    (list (cons "age" age) (cons "dose" dose) (cons "marker" marker)
          (cons "bp" bp) (cons "relapse" relapse)
          (cons "time" (map min event-times censor-times))
          (cons "status" status)))
> (table-column-names patients)

'("age" "dose" "marker" "bp" "relapse" "time" "status")

table->design-matrix converts named columns to a design matrix, which is what the formula front end does before it fits:

> (define D (table->design-matrix patients '("age" dose)))
> D

#<design-matrix 60x2>

> (design-matrix-column-names D)

'("age" "dose")

Only the columns a model reads are checked, so a table can carry other columns, such as an identifier.