23  groupedData

Function nlme::groupedData() (Pinheiro, Bates, and R Core Team 2025, v3.1.168) creates a grouped data frame, i.e., an R object of S3 class 'groupedData'. Listing 23.1 summarizes the S3 methods for the class 'groupedData' in packages nlme,

Listing 23.1: Existing (but not exported) S3 methods nlme::*.groupedData
Code
suppressPackageStartupMessages(library(nlme))
.S3methods(class = 'groupedData', all.names = TRUE) |> 
  attr(which = 'info', exact = TRUE)
#                           visible                from       generic  isS4
# [.groupedData               FALSE registered S3method             [ FALSE
# as.data.frame.groupedData   FALSE registered S3method as.data.frame FALSE
# asTable.groupedData         FALSE registered S3method       asTable FALSE
# collapse.groupedData        FALSE registered S3method      collapse FALSE
# formula.groupedData         FALSE registered S3method       formula FALSE
# isBalanced.groupedData      FALSE registered S3method    isBalanced FALSE
# lme.groupedData             FALSE registered S3method           lme FALSE
# lmList.groupedData          FALSE registered S3method        lmList FALSE
# print.groupedData           FALSE registered S3method         print FALSE
# update.groupedData          FALSE registered S3method        update FALSE

The examples in Chapter 23 require

library(groupedHyperframe)
search path & loadedNamespaces on author’s computer
search()
#  [1] ".GlobalEnv"                "package:groupedHyperframe" "package:stats"             "package:graphics"          "package:grDevices"         "package:utils"             "package:datasets"         
#  [8] "package:methods"           "Autoloads"                 "package:base"
loadedNamespaces() |> sort.int()
#  [1] "abind"             "base"              "cli"               "cluster"           "codetools"         "compiler"          "datasets"          "deldir"            "digest"           
# [10] "doParallel"        "dplyr"             "evaluate"          "farver"            "fastmap"           "fastmatrix"        "foreach"           "generics"          "geomtextpath"     
# [19] "GET"               "ggplot2"           "glue"              "goftest"           "graphics"          "grDevices"         "grid"              "gridExtra"         "groupedHyperframe"
# [28] "gtable"            "htmltools"         "htmlwidgets"       "iterators"         "jsonlite"          "knitr"             "lattice"           "lifecycle"         "magrittr"         
# [37] "Matrix"            "matrixStats"       "methods"           "nlme"              "otel"              "parallel"          "patchwork"         "pillar"            "pkgconfig"        
# [46] "polyclip"          "pracma"            "R6"                "RColorBrewer"      "rlang"             "rmarkdown"         "rstudioapi"        "S7"                "scales"           
# [55] "SpatialPack"       "spatstat.data"     "spatstat.explore"  "spatstat.geom"     "spatstat.random"   "spatstat.sparse"   "spatstat.univar"   "spatstat.utils"    "splines"          
# [64] "stats"             "survival"          "systemfonts"       "tensor"            "textshaping"       "tibble"            "tidyselect"        "tools"             "utils"            
# [73] "vctrs"             "viridisLite"       "xfun"              "yaml"

Table 23.1 summarizes the S3 methods for the class 'groupedData' in package groupedHyperframe (v0.3.4),

Table 23.1: S3 methods groupedHyperframe::*.groupedData (v0.3.4)
visible from generic isS4
as.groupedHyperframe.groupedData TRUE groupedHyperframe groupedHyperframe::as.groupedHyperframe FALSE

23.1 Create groupedHyperframe

The S3 method as.groupedHyperframe.groupedData() (Section 17.1, Table 17.2) converts a grouped data frame into a grouped hyper data frame (groupedHyperframe, Chapter 24) using its grouping structure.

Listing 23.3 converts the grouped data frame Remifentanil (Listing 23.2) from package nlme (Pinheiro, Bates, and R Core Team 2025, v3.1.168) into a grouped hyper data frame.

Listing 23.2: Data: Remifentanil
nlme::Remifentanil
# Grouped Data: conc ~ Time | Subject
#      ID Subject   Time   conc   Rate       Amt   Age    Sex  Ht    Wt    BSA     LBM
# 1     1       1   0.00     NA  71.99  107.9850 30.58   Male 171  72.0 1.8393 56.5075
# 2     1       1   1.50   9.51  71.99   35.9950 30.58   Male 171  72.0 1.8393 56.5075
# 3     1       1   2.00  11.50  71.99   37.4348 30.58   Male 171  72.0 1.8393 56.5075
# ✂️ --- output truncated --- ✂️
Listing 23.3: Example: function as.groupedHyperframe.groupedData() on Remifentanil
Remifentanil_g = nlme::Remifentanil |> 
  as.groupedHyperframe()
Remifentanil_g
# Grouped Hyper Data Frame: ~Subject
# 
# 65 Subject
# 
#         Time      conc      Rate       Amt ID Subject   Age    Sex  Ht    Wt    BSA     LBM
# 1  (numeric) (numeric) (numeric) (numeric) 30      30 21.00 Female 165  55.9 1.6095 42.8260
# 2  (numeric) (numeric) (numeric) (numeric) 21      21 24.00 Female 161  58.6 1.6131 43.0953
# 3  (numeric) (numeric) (numeric) (numeric) 25      25 32.00 Female 157  45.9 1.4278 36.4631
# 4  (numeric) (numeric) (numeric) (numeric) 23      23 23.00 Female 163  50.0 1.5215 39.5740
# 5  (numeric) (numeric) (numeric) (numeric) 29      29 25.00 Female 163  54.5 1.5782 41.7695
# ✂️ --- output truncated --- ✂️

Listing 23.5 converts the grouped data frame bdf (Listing 23.4) from package nlme (Pinheiro, Bates, and R Core Team 2025, v3.1.168) into a grouped hyper data frame.

Listing 23.4: Data: bdf
nlme::bdf
# Grouped Data: langPOST ~ IQ.verb | schoolNR
# <environment: 0x3c2883270>
#      schoolNR pupilNR IQ.verb  IQ.perf sex Minority repeatgr aritPRET classNR aritPOST langPRET langPOST ses denomina schoolSES satiprin natitest meetings currmeet mixedgra percmino aritdiff homework
# 1           1   17001    15.0 12.33333   0        N        0       14     180       24       36       46  23        1        11  3.42857        0  1.70000  1.83333        0       60       12  2.33333
# 2           1   17002    14.5 10.00000   0        Y        0       12     180       19       36       45  10        1        11  3.42857        0  1.70000  1.83333        0       60       12  2.33333
# 3           1   17003     9.5 11.00000   0        N        0       10     180       24       33       33  15        1        11  3.42857        0  1.70000  1.83333        0       60       12  2.33333
# ✂️ --- output truncated --- ✂️
Listing 23.5: Example: function as.groupedHyperframe.groupedData() on bdf
bdf_g = nlme::bdf |> 
  as.groupedHyperframe()
bdf_g
# Grouped Hyper Data Frame: ~schoolNR
# 
# 131 schoolNR
# 
#      pupilNR   IQ.verb   IQ.perf      sex Minority  repeatgr  aritPRET   classNR  aritPOST  langPRET  langPOST       ses mixedgra  percmino  homework  classsiz  groupsiz IQ.ver.cen grpSiz.cen
# 1   (factor) (numeric) (numeric) (factor) (factor) (ordered) (numeric) (numeric) (numeric) (numeric) (numeric) (numeric) (factor) (numeric) (numeric) (numeric) (numeric)  (numeric)  (numeric)
# 2   (factor) (numeric) (numeric) (factor) (factor) (ordered) (numeric) (numeric) (numeric) (numeric) (numeric) (numeric) (factor) (numeric) (numeric) (numeric) (numeric)  (numeric)  (numeric)
# 3   (factor) (numeric) (numeric) (factor) (factor) (ordered) (numeric) (numeric) (numeric) (numeric) (numeric) (numeric) (factor) (numeric) (numeric) (numeric) (numeric)  (numeric)  (numeric)
# 4   (factor) (numeric) (numeric) (factor) (factor) (ordered) (numeric) (numeric) (numeric) (numeric) (numeric) (numeric) (factor) (numeric) (numeric) (numeric) (numeric)  (numeric)  (numeric)
# 5   (factor) (numeric) (numeric) (factor) (factor) (ordered) (numeric) (numeric) (numeric) (numeric) (numeric) (numeric) (factor) (numeric) (numeric) (numeric) (numeric)  (numeric)  (numeric)
# ✂️ --- output truncated --- ✂️

Converting a (grouped) data frame with substantial amount of duplicated information into a grouped hyper data frame not necessarily(!!) reduces the memory allocation (Listing 23.8), because the hyperframe object (Chapter 25) carries additional auxiliary information. And even when it does reduce the memory allocation (Listing 23.6), a grouped hyper data frame would not reduce much the saved file.size compared to a data frame, if xz compression is used for both (Listing 23.7).

Listing 23.6: Advanced: Listing 23.3 reduces memory allocation
unclass(object.size(Remifentanil_g) / object.size(nlme::Remifentanil))
# [1] 0.3083022
Listing 23.7: Advanced: Listing 23.3 does not reduce saved file size
f = replicate(n = 2L, expr = tempfile(fileext = '.rds'))
Remifentanil_g |> saveRDS(file = f[1L], compress = 'xz')
nlme::Remifentanil |> saveRDS(file = f[2L], compress = 'xz')
file.size(f[1L]) / file.size(f[2L])
# [1] 0.9081325
Listing 23.8: Advanced: Listing 23.5 does not reduce memory allocation
unclass(object.size(bdf_g) / object.size(nlme::bdf))
# [1] 25.78675