1.3.6 Polars dataframes🔗ℹ

A dataframe of polars (rkt-polars) is named data. Reading a file with Polars’ read-csv and fitting it is the fast way to fit real data: the predictors leave Polars in one bulk copy, already in the layout the solver reads. Here Polars reads R’s iris from the copy that glmnet/datasets ships:

> (require (only-in polars read-csv column-names dataframe series cast polars-null))
> (define flowers (read-csv (collection-file-path "iris.csv" "glmnet" "datasets")))
> (column-names flowers)

'("Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species")

> (coef (lasso flowers "Sepal.Length" #:lambda 0.01
               #:predictors '("Sepal.Width" "Petal.Length" "Petal.Width")))

'#(2.291509952135093 0.5717696868678742 0.534050705108672 -0.16945221616247616)

A formula reads a dataframe’s columns as a table’s. Its string column, "Species", is a factor:

> (coef (formula-fit (Sepal.Length . ~ . Petal.Width + Species) flowers
                     #:lambda 0.01))

'(("(Intercept)" . 4.799239099455094)

  ("Petal.Width" . 0.8636539037617951)

  ("Speciesversicolor" . 0.0)

  ("Speciesvirginica" . 0.024855955899776596))

A categorical or enum column is a factor too. Its levels are sorted as strings, as a column of strings’ are: the order of an enum’s categories is not kept. R’s factor keeps the order of its levels, so R takes low as the baseline of factor(dose, levels = c("low", "mid", "high")) and fits dosemid and dosehigh, where here "high" is the baseline:

> (define doses
    (dataframe
     (list (series '(1.0 3.2 2.1 0.9 2.0 3.1) #:name "y")
           (cast (series '("low" "high" "mid" "low" "mid" "high") #:name "dose")
                 '(enum low mid high)))))
> (dict-keys (coef (formula-fit (~ y dose) doses #:lambda 0)))

'("(Intercept)" "doselow" "dosemid")

A missing value (a Polars null), a column that is not numeric where numbers are needed, and a value that is not finite are errors that name the column, and the row or the dtype:

> (define gaps
    (dataframe (list (series (list 1.0 2.0 polars-null 4.0) #:name "x")
                     (series '(1.0 2.5 2.9 4.2) #:name "y"))))
> (lasso gaps "y" #:predictors '("x") #:lambda 0.1)

lasso: the dataframe has a missing value

  column: "x"

  row: 2

> (formula-fit (~ Species Petal.Width) flowers #:lambda 0.1)

formula-fit: the response column "Species" is not numeric

  dtype: 'string