PRELIMINARY NOTE

The dscore package is under development, and not yet publicly available. In order to run this document in RStudio, you need to install the dscore package from a private Github repository. If you want to do so, please drop a note to Stef van Buuren to getting a proper access key.

Overview

This vignettes shows how to estimate the D-score and the D-score SDS, a.k.a. DAZ in an excerpt from the POPS data. This vignettes covers some typical actions needed when estimating D-scores:

  1. Rename item names in source data to item names used in itembank
  2. Reorganize the source data into a long matrix
  3. Calculate D-score and DAZ
  4. Combine D-score and DAZ with source data

Rename item names

The dscore package has built-in example data from the POPS study, called popsdemo. The data set is of class tbl_df from the dplyr package.

library("dscore")

popsdemo
## # A tibble: 100 x 67
##    patid gender gestationalage moment   age   occ daycor  dead Fixateseyes
##    <dbl>  <dbl>          <dbl>  <dbl> <dbl> <dbl>  <dbl> <dbl>       <dbl>
##  1     1      2       30.28571      2   161     1     95     0           0
##  2     1      2       30.28571      3   301     2    236     0         NaN
##  3     1      2       30.28571      4   511     3    443     0         NaN
##  4     1      2       30.28571      5  1008     4    940     0         NaN
##  5     4      1       32.42857      2   140     1     93     0           0
##  6     4      1       32.42857      3   231     2    184     0         NaN
##  7     4      1       32.42857      4   420     3    368     0         NaN
##  8     4      1       32.42857      5   763     4    716     0         NaN
##  9     5      1       31.57143      2   147     1     94     0           0
## 10     5      1       31.57143      3   238     2    185     0         NaN
## # ... with 90 more rows, and 58 more variables: Reactstospeech <dbl>,
## #   Movesbotharmsequallyasmuch <dbl>, Movesbothlegsequallyasmuch <dbl>,
## #   Liftschin <dbl>, Smilesback <dbl>, Followswitheyesandhead <dbl>,
## #   Handsopennowandthen <dbl>, Looksatownhands <dbl>,
## #   Vocalizesresponsively <dbl>,
## #   Remainspositionedwhenliftedunderthearmpits <dbl>,
## #   Holdsheadupfortyfivedegreesinproneposition <dbl>,
## #   Handsplayinginmidline <dbl>, Graspstoywithinreach <dbl>,
## #   Noheadlagwhenpulledtosittingposition <dbl>, Turnsheadtosound <dbl>,
## #   Whenliftedverticallylegsbendedortrampling <dbl>,
## #   Holdsheadupninetydegreesinproneposition <dbl>,
## #   Transferstoyeasilyhandtohand <dbl>,
## #   Picksuponesmalltoythensecond <dbl>, Playswithbothfeet <dbl>,
## #   Rollsfrompronetosupineandback <dbl>,
## #   Holdsheadupinsittingposition <dbl>, Sitswithstretchedlegs <dbl>,
## #   Saysdadababaorgaga <dbl>, Sitswithoutsupport <dbl>,
## #   Picksupcrumbbetweenthumbandindexfinger <dbl>, Crawls <dbl>,
## #   Pullshimselftostandingposition <dbl>, Wavesbyebye <dbl>,
## #   Jabbering <dbl>, Getscubeintoandoutofbox <dbl>,
## #   Playsgiveandtake <dbl>, Crawlswithbellyliftedofheground <dbl>,
## #   Walkswhileholdingfurniture <dbl>, Understandssomesimplewords <dbl>,
## #   Usestwowords <dbl>, Makestoweroftwocubes <dbl>, Exploresroom <dbl>,
## #   Usesthreewords <dbl>, Identifiestwonamedobjects <dbl>,
## #   Walksonitsown <dbl>, Throwsballwithoutfalling <dbl>,
## #   Makestowerofthreecubes <dbl>, Imitateseverydayactivities <dbl>,
## #   Drinksfromcup <dbl>, Makestwowordsentences <dbl>,
## #   Putsballinboxwhenasked <dbl>, Squats <dbl>, Walkswell <dbl>,
## #   Makestowerofsixcubes <dbl>, Putsroundfigureintoplace <dbl>,
## #   Takesoffaclothshoesocktrousers <dbl>, Eatswithspoonwithouthelp <dbl>,
## #   CallsitselfbynameorI <dbl>, Identifiespicturesinbook <dbl>,
## #   Kicksballaway <dbl>, dscore <dbl>, daz <dbl>
class(popsdemo)
## [1] "tbl_df"     "tbl"        "data.frame"
nrow(popsdemo)
## [1] 100

The are 25 children and 4 time points.

# 25 children, 4 time points per child
length(unique(popsdemo$patid))
## [1] 25

The item scores that form the test are located in columns 9-65.

test <- 9:65

These names of the columns need to be matched against one of the lexicons in the item bank. The built-in lexicons are:

names(itembank)[1:6]
## [1] "lex.dutch1996" "lex.dutch2005" "lex.dutch1983" "lex.SMOCC"    
## [5] "lex.GHAP"      "lex.jam"

We first need to find out a proper lexicon for the data. For the POPS data, the closest lexicon is . Let us check the variable names in POPS with the item labels in the item bank.

itemset <- !is.na(itembank$lex.dutch1983)
cbind(names(popsdemo)[test], itembank[itemset, c("lex.dutch1983", "labelEN", "tau")])
##                         names(popsdemo)[test] lex.dutch1983
## 1                                 Fixateseyes            v1
## 2                              Reactstospeech            v2
## 3                  Movesbotharmsequallyasmuch            v3
## 6                  Movesbothlegsequallyasmuch            v4
## 9                                   Liftschin            v5
## 10                                 Smilesback            v6
## 11                     Followswitheyesandhead            v7
## 14                        Handsopennowandthen            v8
## 17                            Looksatownhands            v9
## 18                      Vocalizesresponsively           v10
## 19 Remainspositionedwhenliftedunderthearmpits           v11
## 20 Holdsheadupfortyfivedegreesinproneposition           v12
## 23                      Handsplayinginmidline           v13
## 24                       Graspstoywithinreach           v14
## 27       Noheadlagwhenpulledtosittingposition           v15
## 28                           Turnsheadtosound           v16
## 31  Whenliftedverticallylegsbendedortrampling           v17
## 34    Holdsheadupninetydegreesinproneposition           v18
## 35               Transferstoyeasilyhandtohand           v19
## 36               Picksuponesmalltoythensecond           v20
## 37                          Playswithbothfeet           v21
## 40              Rollsfrompronetosupineandback           v22
## 41               Holdsheadupinsittingposition           v23
## 42                      Sitswithstretchedlegs           v24
## 43                         Saysdadababaorgaga           v25
## 45                         Sitswithoutsupport           v26
## 46     Picksupcrumbbetweenthumbandindexfinger           v27
## 49                                     Crawls           v28
## 50             Pullshimselftostandingposition           v29
## 51                                Wavesbyebye           v30
## 52                                  Jabbering           v31
## 54                    Getscubeintoandoutofbox           v32
## 57                           Playsgiveandtake           v33
## 58            Crawlswithbellyliftedofheground           v34
## 59                 Walkswhileholdingfurniture           v35
## 60                 Understandssomesimplewords           v36
## 61                               Usestwowords           v37
## 63                       Makestoweroftwocubes           v38
## 66                               Exploresroom           v39
## 67                             Usesthreewords           v40
## 68                  Identifiestwonamedobjects           v41
## 69                              Walksonitsown           v42
## 70                   Throwsballwithoutfalling           v43
## 74                     Makestowerofthreecubes           v44
## 77                 Imitateseverydayactivities           v45
## 78                              Drinksfromcup           v46
## 79                      Makestwowordsentences           v47
## 80                     Putsballinboxwhenasked           v48
## 81                                     Squats           v49
## 82                                  Walkswell           v50
## 84                       Makestowerofsixcubes           v51
## 85                   Putsroundfigureintoplace           v52
## 86             Takesoffaclothshoesocktrousers           v53
## 87                   Eatswithspoonwithouthelp           v54
## 88                       CallsitselfbynameorI           v55
## 89                   Identifiespicturesinbook           v56
## 90                              Kicksballaway           v57
##                                                          labelEN  tau
## 1                                                    Eyes Fixate  5.4
## 2                                          Reacts when spoken to  1.7
## 3                                        Moves arms equally well -2.2
## 6                                        Moves legs equally well -1.9
## 9                              Lifts chin off table for a moment  5.2
## 10                                            Smiles in response 11.3
## 11                                    Follows with eyes and head 14.5
## 14                                       Hands occasionally open 16.5
## 17                                             Watches own hands 20.7
## 18                                         Vocalizes in response 14.5
## 19                     Stays suspended when lifted under armpits 15.8
## 20                    Lifts head to 45 degrees in prone position 20.0
## 23                                   Plays with hands in midline 28.2
## 24                   Supine position: grasps object within reach 29.9
## 27                                Reactions if pulled to sitting 26.0
## 28                                           Turns head to sound 31.1
## 31                       Flexes or stomps legs while being swung 25.7
## 34         Looks around to side with angle face-table 90 degrees 27.8
## 35                                 Passes cube from hand to hand 36.0
## 36                Holds cube, grasps another one with other hand 36.5
## 37                                          Plays with both feet 33.2
## 40                                    Rolls over, back and forth 34.7
## 41                              Balances head well while sitting 32.5
## 42                         Sits on buttocks while legs stretched 34.9
## 43                                Says "dada", "baba", or "gaga" 36.0
## 45                      Sits in stable position, without support 40.0
## 46                Picks up pellet between thumb and index finger 43.1
## 49                          Crawls forward, abdomen on the floor 43.1
## 50                                 Pulls up to standing position 44.3
## 51                                              Waves "bye bye"  43.1
## 52                  Jabbering while playing (M; can ask parents) 40.9
## 54                                 Puts cube in and out of a box 46.0
## 57                                         Plays "give and take" 46.5
## 58 Crawls, with belly lifted off the ground (M; can ask parents) 46.1
## 59                                                   Walks along 46.1
## 60            Understands some simple words (M; can ask parents) 45.7
## 61                       Says 2 "sound-words" with comprehension 50.1
## 63                                     Builds tower of two cubes 56.4
## 66                                          Explores environment 46.9
## 67                                                Says 3 "words" 53.2
## 68               Identfies (point / graps) two mentioned objects 55.4
## 69                                          Walks on his/her own 51.9
## 70                              Throws ball without falling down 56.0
## 74                                   Builds tower of three cubes 59.2
## 77                                              Imitates others  52.3
## 78            Drink from cup by him/herself (M; can ask parents) 58.5
## 79                                    Says "sentences"of 2 words 60.2
## 80                                   Puts ball in box when asked 57.8
## 81                             Squats or bends to pick up things 55.3
## 82                                       Walks well without help 55.5
## 84                                       Builds tower of 6 cubes 62.6
## 85                                 Places round form in form-box 60.3
## 86                                             Undresses himself 60.6
## 87             Eats with spoon without help (M; can ask parents) 58.5
## 88                              Refers to self using "me" or "I" 61.7
## 89                              Points at 5 pictures in the book 62.2
## 90                                                    Kicks ball 64.2

In this case, we are lucky that all item names from the source data and the item bank match up exactly. In general, we will need to map carefully the names in the dataset to the names in the item bank. For POPS, we may take out the relevant parts of the item bank as

ib <- itembank[itemset,c("lex.dutch1983", "lex.GHAP", "labelEN", "tau")]
head(ib, 3)
##   lex.dutch1983 lex.GHAP                 labelEN  tau
## 1            v1 GSFIXEYE             Eyes Fixate  5.4
## 2            v2  GSRSPCH   Reacts when spoken to  1.7
## 3            v3   GSMARM Moves arms equally well -2.2

From here on, we will work in the GHAP lexicon. Renaming the source data is now done by

names(popsdemo)[test] <- as.character(ib$lex.GHAP)

The source data has now names that are recognized in the itembank. To check this, find the difficulties for each item by the gettau() function:

gettau(names(popsdemo)[test])
## GSFIXEYE  GSRSPCH   GSMARM   GSMLEG GSLFCHIN  GSSMILE   GSFEYE  GSHOPEN 
##      5.4      1.7     -2.2     -1.9      5.2     11.3     14.5     16.5 
##   GSLKHN  GSVOCAL     GSRP   GSHH45 GSHPLAYM    GSGRP GSNOHLAG  GSTHEAD 
##     20.7     14.5     15.8     20.0     28.2     29.9     26.0     31.1 
##  GSLBEND   GSHH90   GSTTOY   GSPTOY   GSPLFT  GSROLLS  GSHHSIT  GSSITST 
##     25.7     27.8     36.0     36.5     33.2     34.7     32.5     34.9 
##   GSSAYS  GSSITWS   GSPICK  GSCRAWL GSPULLST  GSWAVES GSJABBER   GSGETC 
##     36.0     40.0     43.1     43.1     44.3     43.1     40.9     46.0 
## GSPLAYGT  GSCRBLY  GSWALKS GSSIMPLE GSTWOWRD  GSMK2CB  GSEXPLR GSTHRWRD 
##     46.5     46.1     46.1     45.7     50.1     56.4     46.9     53.2 
##  GSIDOBJ GSWLKOWN  GSTBALL  GSMK3CB GSIMITAT GSDRNKCP GSTWOSEN GSPUTBAL 
##     55.4     51.9     56.0     59.2     52.3     58.5     60.2     57.8 
##   GSPKSQ  GSWLKWH  GSMKTW6 GSPUTFIG  GSTKCLO GSEATSPN  GSREFER GSID5OBJ 
##     55.3     55.5     62.6     60.3     60.6     58.5     61.7     62.2 
##    GSKIK 
##     64.2

Reorganize the data into a long matrix

The dscore() function takes vectors of item scores, item names and ages. Rearringing the data makes it easy to extract the relevant vectors. We need to create a data set with the following variables: patid, moment, age, daycor, item and score, and select only the rows where we have an observed score.

library("tidyr")
library("dplyr")
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
data <- popsdemo %>% 
  select(patid, moment, age, daycor, GSFIXEYE:GSKIK) %>%
  gather(items, scores, GSFIXEYE:GSKIK, na.rm = TRUE) %>%
  mutate(scores = 1 - scores) %>% 
  arrange(patid, moment)
## Warning: attributes are not identical across measure variables;
## they will be dropped
data
## # A tibble: 1,385 x 6
##    patid moment   age daycor    items scores
##    <dbl>  <dbl> <dbl>  <dbl>    <chr>  <dbl>
##  1     1      2   161     95 GSFIXEYE      1
##  2     1      2   161     95  GSRSPCH      1
##  3     1      2   161     95   GSMARM      1
##  4     1      2   161     95   GSMLEG      1
##  5     1      2   161     95 GSLFCHIN      1
##  6     1      2   161     95  GSSMILE      1
##  7     1      2   161     95   GSFEYE      1
##  8     1      2   161     95  GSHOPEN      1
##  9     1      2   161     95   GSLKHN      1
## 10     1      2   161     95  GSVOCAL      1
## # ... with 1,375 more rows

There are nrow(data) records with a nonmissing item score. Note also that the item scores have been reversed, as POPS uses a zero for a PASS, and a one for a FAIL.

Calculate D-score and DAZ

For illustration, let us first calculate the D-score of the first child. There are 75 scores for this child, spread over four time points. This is a preterm child, so we correct calener age for gestational age as in daycor:

child1 <- filter(data, patid == 1)

scores <- child1$scores
items <- as.character(child1$items)
ages <- round(child1$daycor/365.25, 4)

# calculate dscore and daz for each time point for given child
(d <- dscore(scores, items, ages))
## 0.2601 0.6461 1.2129 2.5736 
##  25.25  42.73  55.42  70.97
daz(d)
## 0.2601 0.6461 1.2129 2.5736 
##  0.159  0.920  0.788  0.595

If desired, one may also back-calculate the D-score from the standard deviation score by

zad(daz(d))
## 0.2601 0.6461 1.2129 2.5736 
##  25.25  42.73  55.42  70.97

If we specify the child identifier as a by-group variable, we may calculate the D-score and DAZ for all children by

# use age corrected for gestational age
data <- data.frame(data)
data$ages <- round(data$daycor/365.25, 4)

# calculate D-score and DAZ
ds <- split(data, data$patid)
dl <- parallel::mclapply(ds, FUN = dscore)
dazl <- lapply(dl, FUN = daz)
df <- data.frame(
  patid = rep(as.numeric(names(dl)), times = unlist(lapply(dl, length))),
  ages = as.numeric(unlist(lapply(dl, names))),
  dscore = as.numeric(unlist(dl)),
  daz = as.numeric(unlist(dazl)))
head(df)
##   patid   ages dscore    daz
## 1     1 0.2601  25.25  0.159
## 2     1 0.6461  42.73  0.920
## 3     1 1.2129  55.42  0.788
## 4     1 2.5736  70.97  0.595
## 5     4 0.2546  23.15 -0.416
## 6     4 0.5038  31.75 -1.202

Combine D-score and DAZ with source data

Finally, in order to do further analyses, we need to put the estimated D-score and DAZ back into the source data.

# merge dscore and daz into popsdemo data
popsdemo$ages <- round(popsdemo$daycor/365.25, 4)
popsdemo <- merge(popsdemo, df, all.x = TRUE)
head(select(popsdemo, patid, moment, ages, dscore, daz))
##   patid moment   ages dscore    daz
## 1     1      2 0.2601  25.26  0.163
## 2     1      3 0.6461  42.72  0.916
## 3     1      4 1.2129  55.44  0.794
## 4     1      5 2.5736  70.82  0.541
## 5     4      2 0.2546  23.15 -0.416
## 6     4      3 0.5038  31.75 -1.202