Skip to content

DataTables parsing error and popup warnings when anno dataframe contains dots (.) in column names #127

@IgnatiusPang

Description

@IgnatiusPang

Description

When using glimmaXY or glimmaVolcano, if the provided anno dataframe contains columns with dots (.) in their names—which is extremely common in standard R data structures (e.g., P.Value, adj.P.Val, Protein.Ids)—the interactive DataTables table below the plot fails to render properly.

Opening the generated HTML file triggers a DataTables alert popup (e.g., DataTables warning: table id=... - Requested unknown parameter 'Protein.Ids' for row 0, column 1), and the data cells for those specific columns appear blank.

Root Cause Analysis

This is caused by how the DataTables JavaScript library natively handles its data property initialization. By default, DataTables interprets literal dots in the data string property as object property paths for nested JSON objects.

When Glimma converts the R anno dataframe into flat JSON for the frontend, a column named "Protein.Ids" is passed to DataTables in the column configuration as { "data": "Protein.Ids", "title": "Protein.Ids" }. DataTables then attempts to look up row["Protein"]["Ids"]. Because the actual JSON payload is a flat object (e.g., {"Protein.Ids": "P12345"}), DataTables fails to resolve the nested property, triggers the warning popup, and leaves the column blank.

Reproducible Example

library(Glimma)
library(edgeR)

# Create mock expression data
y <- matrix(rnorm(100*6), 100, 6)
rownames(y) <- paste0("Gene", 1:100)

# Create an annotation dataframe with dots in column names
anno_df <- data.frame(
  Gene.ID = rownames(y),
  Gene.Name = paste0("Name", 1:100),
  P.Value = runif(100)
)

# Generate plot
glimmaXY(
  x = rnorm(100), 
  y = -log10(anno_df$P.Value), 
  counts = y, 
  anno = anno_df,
  html = "test_dots_in_names.html"
)

Opening test_dots_in_names.html in a browser will immediately throw the warning popup.

Expected Behavior

The DataTables implementation should be able to cleanly render columns that contain standard R naming conventions like dots, without triggering internal parsing errors or producing blank columns.

Suggested Fix / Workaround

For Maintainers:
Given how ubiquitous dots are in R (data.frame automatically converts spaces and invalid characters to dots, and standard limma/edgeR outputs use P.Value), it would be highly beneficial to add some defensive handling. There are two potential ways to fix this:

Option 1: Escaping dots in JavaScript (preserves original column title)
If you want to keep the dots visually present in the table headers, you can escape the dots in the JS DataTables configuration by using \\. in the data mapping. In htmlwidgets/glimmaXY.js, update the initialization:

const datatable = $(datatableEl).DataTable({
    data: data.xyTable,
    // Escape dots for DataTables' data mapping
    columns: data.cols.map((el) => ({ 
        "data": el.replace(/\./g, '\\\\.'), 
        "title": el 
    })),
    // ...

Option 2: Defensive cleaning in R (easiest)
Before serializing the data to JSON, glimmaXY and glimmaVolcano could defensively sanitize the anno column names:

if (!is.null(anno)) {
  # Defensive check: Replace dots with underscores to prevent DataTables nested object errors
  colnames(anno) <- gsub("\\.", "_", colnames(anno))
}

Temporary User Workaround:
As a temporary fix, R users must proactively manually rename their anno columns to replace dots with underscores before calling the Glimma functions:

colnames(anno_df) <- gsub("\\.", "_", colnames(anno_df))

Environment

  • Glimma Version: 2.20.0 (or current)
  • Browser: Tested on Chrome/Firefox/Safari
  • OS: macOS / Windows

This issue report was written with the assistance of Antigravity (gemini 3 pro) and then manually reviewed to assure correctness and reliability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions