This vignette explains how to perform scale linking with the PROsetta package. By way of illustration, we replicate the linking of the Center for Epidemiologic Studies Depression Scale (CES-D) to the PROMIS Depression metric as described in Choi, Schalet, Cook, and Cella (2014).
First step is to load the input datasets comprised of three tables
with loadData()
. The PROMIS Depression – CES-D linking data
are included in the PROsetta package directory under the folder
labeled data-raw
.
fp <- system.file("data-raw", package = "PROsetta")
d <- loadData(
response = "dat_DeCESD_v2.csv",
itemmap = "imap_DeCESD.csv",
anchor = "anchor_DeCESD.csv",
input_dir = fp)
response
: Contains item response data from both
instruments. You can supply a .csv filename or a data frame. In this
example, we supply a .csv filename dat_DeCESD_v2.csv
.itemmap
: Specifies which items belong to which
instruments. Can be a .csv filename or a data frame.anchor
: Contains tem parameters for anchor items (e.g.,
PROMIS Depression). Can be a .csv filename or a data frame.input_dir
: (Optional) The path of the directory to look
for the input .csv files.The response data contains individual item responses on both instruments (i.e., 28 PROMIS Depression items followed by 20 CES-D items). The data table should include the following columns.
prosettaid
: The person ID of the respondents (N = 747).
This column does not have to be named prosettaid
but should
not conflict with other data tables (item map and anchor).item_id
column in both the item map and anchor files.Run the following code, for example, to open the response data in edit mode.
file.edit(system.file("data-raw", "dat_DeCESD_v2.csv", package = "PROsetta"))
The item map data requires the following columns.
item_id
: Contains the unique ID of the items. The name
of this column does not have to be item_id
but should be
consistent with the item ID column in the anchor table. The IDs in this
column should match the column names in the response data.instrument
: Numerals (1 or 2) indicating to which of
the two instruments the items belong (e.g., 1 = PROMIS Depression; 2 =
CES-D)item_order
: The sequential position of the items in the
combined table (e.g., 1, 2, 3, …, 28, …, 48)item_name
: Secondary labels for the itemsncat
: The number of response categories by itemRun the following code to open the item map data in edit mode.
file.edit(system.file("data-raw", "imap_DeCESD.csv", package = "PROsetta"))
The anchor data contains the item parameters for the anchor scale (e.g., PROMIS Depression) and requires the following columns.
item_order
: The sequential position of the items in the
anchor scale (e.g., 1, 2, 3, …, 28)item_id
: The unique ID of the anchor items. The name of
this column does not have to be item_id
but should be
consistent with the item ID column in the item map table The IDs in this
column should refer to the specific column names in the response
data.a
: The slope parameter value for each anchor itemcb1
, cb2
, …: The category boundary
parameter values for each anchor itemRun the following code to open the anchor data in edit mode.
file.edit(system.file("data-raw", "anchor_DeCESD.csv", package = "PROsetta"))
The frequency distribution of each item in the response data is
obtained by runFrequency()
.
freq_table <- runFrequency(d)
head(freq_table)
## 1 2 3 4 5
## EDDEP04 526 112 66 29 14
## EDDEP05 488 118 91 37 12
## EDDEP06 502 119 85 30 10
## EDDEP07 420 155 107 49 16
## EDDEP09 492 132 89 25 9
## EDDEP14 445 150 101 37 14
The frequency distribution of the summed scores for the combined
scale can be plotted as a histogram with plot()
. The
required argument is a PROsetta_data
object created with
loadData()
. The optional scale
argument
specifies for which scale the summed score should be created. Setting
scale = 'combined'
plots the summed score distribution for
the combined scale.
plot(d, scale = "combined", title = "Combined scale")
The user can also generate the summed score distribution for the
first or second scale by specifying scale = 1
or
scale = 2
.
plot(d, scale = 1, title = "Scale 1") # not run
plot(d, scale = 2, title = "Scale 2") # not run
Basic descriptive statistics are obtained for each item by
runDescriptive()
.
desc_table <- runDescriptive(d)
head(desc_table)
## n mean sd median trimmed mad min max range skew kurtosis se
## EDDEP04 747 1.52 0.94 1 1.30 0 1 5 4 1.91 3.01 0.03
## EDDEP05 746 1.62 0.99 1 1.42 0 1 5 4 1.54 1.50 0.04
## EDDEP06 746 1.56 0.94 1 1.37 0 1 5 4 1.66 2.01 0.03
## EDDEP07 747 1.78 1.05 1 1.59 0 1 5 4 1.23 0.59 0.04
## EDDEP09 747 1.56 0.91 1 1.38 0 1 5 4 1.62 1.98 0.03
## EDDEP14 747 1.69 1.00 1 1.51 0 1 5 4 1.38 1.12 0.04
Classical reliability statistics can be obtained by
runClassical()
. By default, the analysis is performed for
the combined scale.
classical_table <- runClassical(d)
summary(classical_table$alpha$combined)
##
## Reliability analysis
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd median_r
## 0.98 0.98 0.99 0.53 54 9e-04 1.7 0.69 0.54
The user can set scalewise = TRUE
to request an analysis
for each scale separately in addition to the combined scale.
classical_table <- runClassical(d, scalewise = TRUE)
classical_table$alpha$combined # alpha values for combined scale
classical_table$alpha$`1` # alpha values for each scale, created when scalewise = TRUE
classical_table$alpha$`2` # alpha values for each scale, created when scalewise = TRUE
Specifying omega = TRUE
returns the McDonald’s \(\omega\) coefficients as well.
classical_table <- runClassical(d, scalewise = TRUE, omega = TRUE)
classical_table$omega$combined # omega values for combined scale
classical_table$omega$`1` # omega values for each scale, created when scalewise = TRUE
classical_table$omega$`2` # omega values for each scale, created when scalewise = TRUE
Additional arguments can be supplied to runClassical()
to pass onto psych::omega()
.
classical_table <- runClassical(d, scalewise = TRUE, omega = TRUE, nfactors = 5) # not run
Dimensionality analysis is performed with CFA by
runCFA()
. Setting scalewise = TRUE
performs
the dimensionality analysis for each scale separately in addition to the
combined scale.
out_cfa <- runCFA(d, scalewise = TRUE)
runCFA()
calls for lavaan::cfa()
internally
and can pass additional arguments onto it.
out_cfa <- runCFA(d, scalewise = TRUE, std.lv = TRUE) # not run
The CFA result for the combined scale is stored in the
combined
slot, and if scalewise = TRUE
, the
analysis for each scale is also stored in each numbered slot.
out_cfa$combined
## lavaan 0.6-12 ended normally after 23 iterations
##
## Estimator DWLS
## Optimization method NLMINB
## Number of model parameters 220
##
## Used Total
## Number of observations 731 747
##
## Model Test User Model:
## Standard Robust
## Test Statistic 4227.611 4700.781
## Degrees of freedom 1080 1080
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 1.046
## Shift parameter 657.455
## simple second-order correction
out_cfa$`1`
## lavaan 0.6-12 ended normally after 16 iterations
##
## Estimator DWLS
## Optimization method NLMINB
## Number of model parameters 140
##
## Used Total
## Number of observations 738 747
##
## Model Test User Model:
## Standard Robust
## Test Statistic 863.527 1434.277
## Degrees of freedom 350 350
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 0.678
## Shift parameter 160.257
## simple second-order correction
out_cfa$`2`
## lavaan 0.6-12 ended normally after 20 iterations
##
## Estimator DWLS
## Optimization method NLMINB
## Number of model parameters 80
##
## Used Total
## Number of observations 740 747
##
## Model Test User Model:
## Standard Robust
## Test Statistic 1106.148 1431.797
## Degrees of freedom 170 170
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 0.812
## Shift parameter 69.205
## simple second-order correction
CFA fit indices can be obtained by using summary()
from
the lavaan package. For the combined scale:
lavaan::summary(out_cfa$combined, fit.measures = TRUE, standardized = TRUE, estimates = FALSE)
## lavaan 0.6-12 ended normally after 23 iterations
##
## Estimator DWLS
## Optimization method NLMINB
## Number of model parameters 220
##
## Used Total
## Number of observations 731 747
##
## Model Test User Model:
## Standard Robust
## Test Statistic 4227.611 4700.781
## Degrees of freedom 1080 1080
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 1.046
## Shift parameter 657.455
## simple second-order correction
##
## Model Test Baseline Model:
##
## Test statistic 793198.138 91564.633
## Degrees of freedom 1128 1128
## P-value 0.000 0.000
## Scaling correction factor 8.758
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.996 0.960
## Tucker-Lewis Index (TLI) 0.996 0.958
##
## Robust Comparative Fit Index (CFI) NA
## Robust Tucker-Lewis Index (TLI) NA
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.063 0.068
## 90 Percent confidence interval - lower 0.061 0.066
## 90 Percent confidence interval - upper 0.065 0.070
## P-value RMSEA <= 0.05 0.000 0.000
##
## Robust RMSEA NA
## 90 Percent confidence interval - lower NA
## 90 Percent confidence interval - upper NA
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.051 0.051
and also for each scale separately:
lavaan::summary(out_cfa$`1`, fit.measures = TRUE, standardized = TRUE, estimates = FALSE) # not run
lavaan::summary(out_cfa$`2`, fit.measures = TRUE, standardized = TRUE, estimates = FALSE) # not run
runCalibration()
performs IRT calibration without
anchoring. runCalibration()
calls mirt::mirt()
internally. Additional arguments can be passed onto mirt
,
e.g., to increase the number of EM cycles to 1000, as follows:
out_calib <- runCalibration(d, technical = list(NCYCLES = 1000))
In case of nonconvergence, runCalibration()
explicitly
raises an error and does not return its results.
out_calib <- runCalibration(d, technical = list(NCYCLES = 10))
## Error in runCalibration(d, technical = list(NCYCLES = 10)): calibration did not converge: increase iteration limit by adjusting the 'technical' argument, e.g., technical = list(NCYCLES = 510)
Also, specify fixedpar = TRUE
to perform fixed parameter
calibration using the anchor data.
out_calib <- runCalibration(d, fixedpar = TRUE)
The output object from runCalibration()
can be used to
generate additional output with functions from the mirt
package.
Use coef()
to extract item parameters:
mirt::coef(out_calib, IRTpars = TRUE, simplify = TRUE)
## $items
## a b1 b2 b3 b4
## EDDEP04 4.261 0.401 0.976 1.696 2.444
## EDDEP05 3.932 0.305 0.913 1.593 2.412
## EDDEP06 4.145 0.350 0.915 1.678 2.471
## EDDEP07 2.802 0.148 0.772 1.603 2.538
## EDDEP09 3.657 0.312 0.982 1.782 2.571
## EDDEP14 2.333 0.186 0.947 1.729 2.633
## EDDEP17 3.274 -0.498 0.406 1.413 2.375
## EDDEP19 3.241 0.460 1.034 1.834 2.515
## EDDEP21 2.736 0.072 0.810 1.803 2.673
## EDDEP22 3.970 0.204 0.795 1.649 2.295
## EDDEP23 2.564 -0.038 0.693 1.653 2.584
## EDDEP26 3.093 -0.358 0.412 1.404 2.224
## EDDEP27 2.920 0.204 0.891 1.655 2.528
## EDDEP28 2.588 -0.079 0.633 1.477 2.328
## EDDEP29 4.343 -0.117 0.598 1.428 2.272
## EDDEP30 2.613 -0.023 0.868 1.864 2.826
## EDDEP31 3.183 -0.261 0.397 1.305 2.134
## EDDEP35 3.106 0.044 0.722 1.639 2.471
## EDDEP36 3.483 -0.536 0.348 1.347 2.355
## EDDEP39 3.131 0.918 1.481 2.164 2.856
## EDDEP41 4.454 0.558 1.074 1.779 2.530
## EDDEP42 2.364 0.210 0.987 1.906 2.934
## EDDEP44 2.549 0.194 1.012 2.013 3.126
## EDDEP45 2.834 0.141 0.907 1.846 2.875
## EDDEP46 2.381 -0.458 0.478 1.546 2.632
## EDDEP48 3.185 0.198 0.782 1.526 2.324
## EDDEP50 2.018 -0.050 0.926 2.000 2.966
## EDDEP54 2.685 -0.299 0.423 1.358 2.308
## CESD1 2.074 0.876 1.921 3.064 NA
## CESD2 1.262 1.387 2.670 3.721 NA
## CESD3 3.512 0.833 1.316 1.949 NA
## CESD4 1.118 0.649 1.379 2.081 NA
## CESD5 1.605 0.429 1.526 2.724 NA
## CESD6 3.635 0.493 1.176 1.729 NA
## CESD7 1.828 0.287 1.368 2.134 NA
## CESD8 1.342 -0.067 0.823 1.620 NA
## CESD9 3.003 0.748 1.374 1.855 NA
## CESD10 2.060 1.172 2.043 3.268 NA
## CESD11 1.077 -0.463 0.947 2.160 NA
## CESD12 2.229 0.169 0.945 1.737 NA
## CESD13 1.288 0.342 1.696 2.915 NA
## CESD14 2.176 0.491 1.291 1.864 NA
## CESD15 1.397 0.965 2.321 3.604 NA
## CESD16 2.133 0.272 0.922 1.808 NA
## CESD17 1.719 1.607 2.317 3.470 NA
## CESD18 2.812 0.261 1.248 1.984 NA
## CESD19 1.834 0.784 1.875 2.639 NA
## CESD20 1.491 -0.140 1.256 2.297 NA
##
## $means
## F1
## -0.06
##
## $cov
## F1
## F1 0.95
and also other commonly used functions:
mirt::itemfit(out_calib, empirical.plot = 1)
mirt::itemplot(out_calib, item = 1, type = "info")
mirt::itemfit(out_calib, "S_X2", na.rm = TRUE)
Scale information functions can be plotted with
plotInfo
. The two required arguments are an output object
from runCalibration()
and a PROsetta
object
from loadData()
. The additional arguments specify the
labels, colors, and line types for each scale and the combined scale.
The last values in arguments scale_label
,
color
, lty
represent the values for the
combined scale.
plotInfo(
out_calib, d,
scale_label = c("PROMIS Depression", "CES-D", "Combined"),
color = c("blue", "red", "black"),
lty = c(1, 2, 3))
runLinking()
performs item parameter linking based on
the anchor item parameters supplied in the anchor
table.
Two linking, or more specifically scaling aligning, methods currently
available are fixed-parameter calibration and linear transformation.
Fixed-parameter calibration estimates the item parameters for the
non-anchor items on the metric defined by the anchor items, while fixing
the item parameters for the anchor items to their supplied anchor
values. The linear transformation methods determine linear
transformation constants, i.e., a slope and an intercept, to transform
freely estimated item parameters to the metric defined by the anchor
items.
Scale aligning through fixed parameter calibration is performed by
setting method = "FIXEDPAR"
. The linked parameters are
stored in the $ipar_linked
slot.
out_link_fixedpar <- runLinking(d, method = "FIXEDPAR")
out_link_fixedpar$ipar_linked
## a b1 b2 b3 b4
## EDDEP04 4.261422 0.40106943 0.9756732 1.696300 2.444072
## EDDEP05 3.931743 0.30494182 0.9130961 1.593476 2.411682
## EDDEP06 4.144759 0.35011299 0.9153482 1.678203 2.470526
## EDDEP07 2.801804 0.14774854 0.7723478 1.602715 2.538057
## EDDEP09 3.657433 0.31195821 0.9818088 1.782108 2.571127
## EDDEP14 2.333381 0.18599340 0.9473173 1.728770 2.632643
## EDDEP17 3.274033 -0.49845044 0.4059439 1.413052 2.375459
## EDDEP19 3.240973 0.46049359 1.0344267 1.833595 2.514716
## EDDEP21 2.736104 0.07245992 0.8097820 1.803067 2.673441
## EDDEP22 3.970028 0.20379963 0.7954889 1.648707 2.295496
## EDDEP23 2.564431 -0.03841113 0.6926952 1.652820 2.583629
## EDDEP26 3.093368 -0.35762208 0.4124999 1.403863 2.223961
## EDDEP27 2.920056 0.20434012 0.8909159 1.654652 2.528368
## EDDEP28 2.588339 -0.07908821 0.6326205 1.477330 2.327715
## EDDEP29 4.342918 -0.11730304 0.5977487 1.428166 2.272495
## EDDEP30 2.612846 -0.02337743 0.8683854 1.864303 2.826340
## EDDEP31 3.182866 -0.26089392 0.3967655 1.305464 2.133989
## EDDEP35 3.105857 0.04371372 0.7223523 1.638758 2.471487
## EDDEP36 3.483012 -0.53588456 0.3475707 1.346781 2.354790
## EDDEP39 3.131213 0.91802061 1.4813240 2.163996 2.856377
## EDDEP41 4.454157 0.55838282 1.0742430 1.779346 2.530080
## EDDEP42 2.364413 0.21006534 0.9870936 1.905901 2.933758
## EDDEP44 2.549164 0.19350024 1.0117460 2.013109 3.126494
## EDDEP45 2.833605 0.14071213 0.9065001 1.846097 2.875194
## EDDEP46 2.380628 -0.45788346 0.4779996 1.545663 2.631512
## EDDEP48 3.185244 0.19814448 0.7819065 1.525815 2.324082
## EDDEP50 2.018099 -0.05044210 0.9258678 1.999516 2.965507
## EDDEP54 2.685300 -0.29880847 0.4234598 1.357851 2.307647
## CESD1 2.074445 0.87587980 1.9208504 3.063586 NA
## CESD2 1.262451 1.38731908 2.6695203 3.720537 NA
## CESD3 3.512494 0.83271835 1.3159723 1.948793 NA
## CESD4 1.118259 0.64882086 1.3786366 2.081168 NA
## CESD5 1.604925 0.42935048 1.5261799 2.723722 NA
## CESD6 3.634682 0.49267510 1.1756145 1.729145 NA
## CESD7 1.827677 0.28707354 1.3677917 2.134161 NA
## CESD8 1.341785 -0.06692847 0.8227656 1.619582 NA
## CESD9 3.002593 0.74752430 1.3741494 1.855368 NA
## CESD10 2.060397 1.17177985 2.0425550 3.268036 NA
## CESD11 1.076594 -0.46319567 0.9471561 2.159803 NA
## CESD12 2.229317 0.16859300 0.9449514 1.736562 NA
## CESD13 1.288446 0.34213364 1.6959382 2.915160 NA
## CESD14 2.176409 0.49140719 1.2914086 1.864274 NA
## CESD15 1.396545 0.96457777 2.3205004 3.603938 NA
## CESD16 2.132819 0.27238868 0.9216834 1.808275 NA
## CESD17 1.718814 1.60657466 2.3169957 3.469720 NA
## CESD18 2.812166 0.26144306 1.2484436 1.984111 NA
## CESD19 1.833678 0.78350055 1.8751245 2.638591 NA
## CESD20 1.490736 -0.14037553 1.2558583 2.296856 NA
Scale aligning through linear transformation is performed by setting
the method
argument to one of the following options:
MM
(Mean-Mean)MS
(Mean-Sigma)HB
(Haebara)SL
(Stocking-Lord)Arguments supplied to runLinking
are passed onto
mirt::mirt()
internally. In case of nonconvergence in the
free calibration step, runLinking()
explicitly raises an
error and does not return its results.
out_link_sl <- runLinking(d, method = "SL", technical = list(NCYCLES = 1000))
out_link_sl
The item parameter estimates linked to the anchor metric are stored
in the $ipar_linked
slot.
out_link_sl$ipar_linked
## a b1 b2 b3 b4
## EDDEP04 3.793029 0.469533419 1.0795406 1.723902 2.349076
## EDDEP05 3.320320 0.332904767 0.8987386 1.652727 2.495477
## EDDEP06 3.425877 0.387805690 1.0150119 1.791368 2.554674
## EDDEP07 2.515474 0.079236063 0.8041343 1.613014 2.489916
## EDDEP09 3.473048 0.333927504 1.0061990 1.872558 2.581146
## EDDEP14 2.593291 0.166260477 0.8908936 1.766002 2.578976
## EDDEP17 3.271608 -0.484050471 0.3934660 1.378820 2.485099
## EDDEP19 3.288428 0.594096436 1.1569718 1.908310 2.491023
## EDDEP21 2.658923 -0.008882325 0.7996174 1.769780 2.587520
## EDDEP22 3.694358 0.202955639 0.7692498 1.679949 2.211220
## EDDEP23 2.558588 -0.112440314 0.6118746 1.527154 2.413624
## EDDEP26 2.978910 -0.359701075 0.4134187 1.383127 2.206001
## EDDEP27 2.945536 0.220219711 0.9013557 1.670466 2.546553
## EDDEP28 2.533107 -0.089890503 0.6379712 1.516826 2.353173
## EDDEP29 3.641904 -0.108954603 0.6340889 1.413201 2.313965
## EDDEP30 2.366319 -0.144281621 0.8036436 1.852478 2.826827
## EDDEP31 2.859289 -0.272674891 0.3784911 1.397100 2.247130
## EDDEP35 2.833400 -0.091130728 0.6508356 1.594374 2.513013
## EDDEP36 3.831011 -0.409409474 0.4298683 1.362455 2.182989
## EDDEP39 2.921653 1.013215272 1.5973689 2.147484 2.830992
## EDDEP41 4.290437 0.403883160 1.0501889 1.653616 2.444900
## EDDEP42 2.203137 -0.061877213 0.8051795 1.819106 2.845096
## EDDEP44 2.487190 0.265079589 1.0154005 2.024892 3.207734
## EDDEP45 2.598372 0.071893618 0.9289162 2.065913 2.910977
## EDDEP46 2.580533 -0.300955547 0.4971943 1.463756 2.349171
## EDDEP48 3.192216 0.301875858 0.7763997 1.670601 2.269179
## EDDEP50 2.171915 0.094997587 0.9605642 1.915712 2.757289
## EDDEP54 2.962318 -0.178813060 0.5521151 1.377952 2.253454
## CESD1 2.061766 0.879472041 1.9314954 3.076894 NA
## CESD2 1.255555 1.392412845 2.6815805 3.738036 NA
## CESD3 3.508720 0.837487777 1.3247626 1.957234 NA
## CESD4 1.111396 0.650008215 1.3850762 2.091835 NA
## CESD5 1.593890 0.428584353 1.5343145 2.738418 NA
## CESD6 3.618542 0.492974797 1.1842614 1.739734 NA
## CESD7 1.811272 0.285423868 1.3764430 2.148180 NA
## CESD8 1.332344 -0.070808355 0.8265583 1.629127 NA
## CESD9 2.980139 0.751489716 1.3836674 1.866733 NA
## CESD10 2.054286 1.176190190 2.0499513 3.277144 NA
## CESD11 1.072253 -0.469508431 0.9481333 2.166834 NA
## CESD12 2.220276 0.164845361 0.9489171 1.745283 NA
## CESD13 1.279645 0.340719364 1.7050024 2.932273 NA
## CESD14 2.165041 0.490997420 1.2981459 1.874621 NA
## CESD15 1.388292 0.967788618 2.3321665 3.621479 NA
## CESD16 2.119591 0.270264210 0.9262708 1.818614 NA
## CESD17 1.720559 1.609378397 2.3204249 3.472174 NA
## CESD18 2.803338 0.257881796 1.2547127 1.992338 NA
## CESD19 1.820451 0.786212216 1.8859179 2.652886 NA
## CESD20 1.482219 -0.145775604 1.2604344 2.307635 NA
Transformation constants (A = slope; B = intercept) for the specified
linear transformation method are stored in the $constants
slot.
out_link_sl$constants
## A B
## 0.982324 -0.064233
From the item parameter estimates transformed to the anchor metric,
raw-score-to-scale-score (rsss) crosswalk tables can be generated by
runRSSS()
.
The output from runRSSS()
includes three crosswalk
tables (labeled as 1
, 2
, and
combined
), one for each scale and the third one for the
combined scale. Each table contains raw summed scores and corresponding
scaled scores, including summed score EAP estimate, T-scores
corresponding to the EAP estimates, as well as expected summed scores
(i.e., true scores) for each scale from the EAP estimates.
rsss_fixedpar <- runRSSS(d, out_link_fixedpar)
rsss_sl <- runRSSS(d, out_link_sl)
round(rsss_fixedpar$`2`, 3)
## raw_2 tscore tscore_se eap eap_se escore_1 escore_2 escore_combined
## 1 20 34.5 6.0 -1.554 0.599 28.455 21.105 49.560
## 2 21 38.6 5.1 -1.139 0.509 29.340 21.851 51.192
## 3 22 41.1 4.7 -0.892 0.473 30.503 22.523 53.026
## 4 23 42.9 4.5 -0.713 0.455 31.837 23.154 54.991
## 5 24 44.7 4.1 -0.534 0.412 33.735 23.950 57.685
## 6 25 46.2 3.8 -0.382 0.382 35.853 24.777 60.630
## 7 26 47.5 3.6 -0.248 0.357 38.134 25.636 63.769
## 8 27 48.7 3.3 -0.128 0.335 40.558 26.535 67.093
## 9 28 49.8 3.2 -0.020 0.316 43.052 27.459 70.511
## 10 29 50.8 3.0 0.080 0.300 45.580 28.401 73.981
## 11 30 51.7 2.9 0.171 0.287 48.114 29.358 77.471
## 12 31 52.6 2.8 0.256 0.275 50.629 30.324 80.953
## 13 32 53.4 2.7 0.336 0.266 53.105 31.297 84.402
## 14 33 54.1 2.6 0.411 0.257 55.527 32.273 87.801
## 15 34 54.8 2.5 0.482 0.250 57.886 33.251 91.137
## 16 35 55.5 2.4 0.550 0.244 60.176 34.228 94.405
## 17 36 56.2 2.4 0.615 0.239 62.397 35.205 97.601
## 18 37 56.8 2.3 0.678 0.235 64.549 36.179 100.728
## 19 38 57.4 2.3 0.739 0.231 66.637 37.152 103.788
## 20 39 58.0 2.3 0.798 0.228 68.665 38.122 106.788
## 21 40 58.6 2.3 0.856 0.225 70.639 39.092 109.731
## 22 41 59.1 2.2 0.912 0.223 72.564 40.060 112.625
## 23 42 59.7 2.2 0.967 0.221 74.444 41.029 115.472
## 24 43 60.2 2.2 1.022 0.219 76.283 41.997 118.280
## 25 44 60.8 2.2 1.075 0.218 78.086 42.965 121.051
## 26 45 61.3 2.2 1.128 0.216 79.858 43.933 123.792
## 27 46 61.8 2.2 1.181 0.215 81.604 44.902 126.506
## 28 47 62.3 2.1 1.233 0.215 83.329 45.871 129.200
## 29 48 62.8 2.1 1.285 0.214 85.038 46.840 131.878
## 30 49 63.4 2.1 1.336 0.214 86.737 47.810 134.547
## 31 50 63.9 2.1 1.388 0.214 88.432 48.780 137.211
## 32 51 64.4 2.1 1.439 0.214 90.126 49.750 139.875
## 33 52 64.9 2.1 1.491 0.214 91.823 50.721 142.544
## 34 53 65.4 2.1 1.543 0.215 93.528 51.692 145.220
## 35 54 65.9 2.2 1.595 0.216 95.241 52.666 147.907
## 36 55 66.5 2.2 1.647 0.217 96.965 53.640 150.605
## 37 56 67.0 2.2 1.701 0.218 98.700 54.616 153.316
## 38 57 67.5 2.2 1.755 0.220 100.446 55.594 156.040
## 39 58 68.1 2.2 1.809 0.222 102.205 56.572 158.777
## 40 59 68.7 2.2 1.865 0.225 103.978 57.549 161.528
## 41 60 69.2 2.3 1.922 0.227 105.768 58.526 164.294
## 42 61 69.8 2.3 1.980 0.231 107.579 59.499 167.078
## 43 62 70.4 2.3 2.040 0.234 109.416 60.467 169.884
## 44 63 71.0 2.4 2.101 0.239 111.287 61.429 172.716
## 45 64 71.6 2.4 2.164 0.243 113.196 62.383 175.579
## 46 65 72.3 2.5 2.230 0.248 115.149 63.326 178.476
## 47 66 73.0 2.5 2.297 0.254 117.147 64.259 181.407
## 48 67 73.7 2.6 2.367 0.260 119.185 65.181 184.366
## 49 68 74.4 2.7 2.440 0.267 121.251 66.091 187.342
## 50 69 75.2 2.7 2.517 0.274 123.325 66.991 190.316
## 51 70 76.0 2.8 2.597 0.282 125.381 67.883 193.263
## 52 71 76.8 2.9 2.682 0.290 127.385 68.767 196.152
## 53 72 77.7 3.0 2.772 0.299 129.304 69.647 198.951
## 54 73 78.7 3.1 2.868 0.308 131.104 70.522 201.626
## 55 74 79.7 3.2 2.970 0.316 132.754 71.393 204.147
## 56 75 80.8 3.2 3.079 0.323 134.224 72.253 206.478
## 57 76 81.9 3.3 3.195 0.326 135.490 73.090 208.580
## 58 77 83.1 3.2 3.314 0.322 136.534 73.882 210.416
## 59 78 84.3 3.1 3.433 0.310 137.354 74.604 211.959
## 60 79 85.5 2.9 3.549 0.287 137.973 75.238 213.211
## 61 80 86.5 2.6 3.654 0.256 138.415 75.762 214.177
The columns in the crosswalk tables include:
raw_1
: raw summed score in Scale 1 (also
raw_2
for Scale 2 and raw_3
for the
combined)tscore
: T-score corresponding to each summed scoretscore_se
: standard error associated with each
T-scoreeap
: summed score EAP equivalent for each raw summed
scoreeap_se
: standard error associated with each EAP
estimateescore_1
: expected summed score (true score) for Scale
1 given the EAP estimateescore_2
: expected summed score (true score) for Scale
2 given the EAP estimateescore_combined
: expected summed score (true score) for
the combined scale given the EAP estimateEquipercentile linking of observed summed scores is performed by
runEquateObserved()
.
Cases with missing responses are removed to be able to generate correct summed scores in concordance tables.
This function requires four arguments:
scale_from
: numeric index of the scale (as specified in
the item map) to be linkedscale_to
: numeric index of the scale (as specified in
the item map) to serve as the anchoreq_type
: the type of equating to be performed,
equipercentile
for this example. See
?equate::equate
for details.smooth
: the type of presmoothing to performBy default, runEquateObserved()
performs raw-raw
equipercentile linking. In this example, each raw summed score in Scale
2 (CES-D, ranging from 20 to 80) is linked to a raw summed score
equivalent in Scale 1 (PROMIS Depression, rangeing from 28 to 140) with
loglinear presmoothing.
out_equate <- runEquateObserved(
d, scale_from = 2, scale_to = 1,
eq_type = "equipercentile", smooth = "loglinear")
The crosswalk table can be obtained from the concordance
slot:
out_equate$concordance
## raw_2 raw_1 raw_1_se raw_1_se_boot
## 1 20 28.26881 0.1620936 0.1212081
## 2 21 29.88299 0.3370778 0.3303319
## 3 22 31.53492 0.5039397 0.5115951
## 4 23 33.26052 0.6025077 0.6923284
## 5 24 35.04116 0.7605541 0.8854782
## 6 25 36.88206 0.9289581 1.0971580
## 7 26 38.78932 1.1047990 1.2837501
## 8 27 40.76619 1.2851847 1.4402608
## 9 28 42.81301 1.4675514 1.5873638
## 10 29 44.92722 1.6498695 1.8041498
## 11 30 47.10359 1.8307274 2.0437826
## 12 31 49.33456 2.0092834 2.2020250
## 13 32 51.61601 2.2830630 2.3246494
## 14 33 53.93979 2.4363247 2.4949351
## 15 34 56.28523 2.5838111 2.7351693
## 16 35 58.64518 2.8128224 2.9756616
## 17 36 61.00920 2.9230117 3.1978044
## 18 37 63.35840 3.0265741 3.3909264
## 19 38 65.68830 3.1931417 3.6307289
## 20 39 67.98827 3.2579872 3.6598381
## 21 40 70.24833 3.3160014 3.7765044
## 22 41 72.46413 3.3666557 3.9085640
## 23 42 74.63553 3.4696445 3.9457373
## 24 43 76.75786 3.4943506 4.0502954
## 25 44 78.83013 3.5156665 4.0966580
## 26 45 80.85299 3.5347321 4.2549196
## 27 46 82.82775 3.5532238 4.1621103
## 28 47 84.75618 3.5733950 4.1163935
## 29 48 86.64034 3.5981071 4.1366881
## 30 49 88.48280 3.5457997 3.8788945
## 31 50 90.28977 3.5652250 3.8315545
## 32 51 92.06044 3.5948509 3.8382998
## 33 52 93.79686 3.6397275 3.8557030
## 34 53 95.50073 3.7057230 3.9071801
## 35 54 97.18390 3.6406951 3.7867319
## 36 55 98.83962 3.7115896 3.5577836
## 37 56 100.46992 3.6731482 3.4986295
## 38 57 102.08880 3.7516801 3.5051241
## 39 58 103.68535 3.8710358 3.4598704
## 40 59 105.27044 3.8253417 3.5677692
## 41 60 106.84491 3.9636676 3.6371879
## 42 61 108.40599 3.9344712 3.6556593
## 43 62 109.96920 4.0965312 3.8607023
## 44 63 111.51836 4.3289986 3.8679308
## 45 64 113.08139 4.2728002 3.9250780
## 46 65 114.63738 4.5418401 4.3885043
## 47 66 116.20861 4.4956647 4.6145764
## 48 67 117.78972 4.7999844 4.5686764
## 49 68 119.38584 4.7678715 4.5641391
## 50 69 121.01883 5.0971545 4.9950317
## 51 70 122.67774 5.5168449 5.7126031
## 52 71 124.38914 5.4272766 6.1297428
## 53 72 126.17776 5.8150222 6.0529385
## 54 73 128.05913 6.2277413 5.9644172
## 55 74 130.07996 6.6010857 6.1798800
## 56 75 132.31127 6.8333301 5.8076621
## 57 76 134.91376 7.4633808 5.0579755
## 58 77 138.21074 6.3457311 3.5448070
Raw summed scores can be linked to scaled scores (e.g., T-scores)
directly by specifying type_to = 'tscore'
in
runEquateObserved()
. In the following example, we map the
raw summed scores from Scale 2 (CES-D, ranging from 20 to 80) onto the
T-score equivalents in Scale 1 (PROMIS Depression, mean = 50 and SD =
10).
out_equate_tscore <- runEquateObserved(
d, scale_from = 2, scale_to = 1,
type_to = "tscore", rsss = rsss_fixedpar,
eq_type = "equipercentile", smooth = "loglinear")
Again, the crosswalk table can be retrieved from the
concordance
slot:
out_equate_tscore$concordance
## raw_2 tscore_1 tscore_1_se tscore_1_se_boot
## 1 20 33.60138 0.1015887 0.4050093
## 2 21 38.46567 0.2970127 1.0894772
## 3 22 41.72102 0.5244657 0.5193193
## 4 23 43.93269 0.7283759 0.5932143
## 5 24 45.56073 0.9008862 0.5860808
## 6 25 46.96056 1.0676547 0.6304543
## 7 26 48.14591 1.2231568 0.6111083
## 8 27 49.15361 1.4254088 0.6300490
## 9 28 50.08462 1.5481891 0.6457005
## 10 29 50.93574 1.6767468 0.6444944
## 11 30 51.69914 1.7912740 0.6254665
## 12 31 52.45221 1.9745160 0.6410030
## 13 32 53.09555 2.0699538 0.6475026
## 14 33 53.81778 2.1925590 0.6525931
## 15 34 54.43935 2.2939903 0.6730943
## 16 35 55.05249 2.3979162 0.6701021
## 17 36 55.65876 2.5043386 0.6817231
## 18 37 56.19032 2.5834537 0.7207839
## 19 38 56.74801 2.6939470 0.7669222
## 20 39 57.33437 2.8072216 0.7818320
## 21 40 57.91858 2.9233371 0.7913626
## 22 41 58.49310 3.0422752 0.7892159
## 23 42 58.98081 3.1276569 0.8566448
## 24 43 59.55737 3.2512041 0.8808118
## 25 44 60.13559 3.2571331 0.9178861
## 26 45 60.71592 3.3751754 0.9517731
## 27 46 61.29874 3.4950840 0.9336538
## 28 47 61.88462 3.6164946 0.9271969
## 29 48 62.38451 3.6947613 0.9754445
## 30 49 62.95738 3.8157601 1.0011474
## 31 50 63.54690 3.9367948 1.0507005
## 32 51 64.14007 4.0572121 1.0910304
## 33 52 64.73684 4.1763139 1.1202394
## 34 53 65.33702 4.2933638 1.2103442
## 35 54 65.94024 4.4075839 1.2492009
## 36 55 66.54594 4.5181439 1.3088524
## 37 56 67.24018 4.6807053 1.3751377
## 38 57 67.87194 4.7833243 1.4762335
## 39 58 68.48824 4.8795677 1.4586861
## 40 59 69.10342 4.9680991 1.4123647
## 41 60 69.76017 5.0472563 1.4430387
## 42 61 70.43094 5.1798624 1.4920188
## 43 62 71.04031 5.2369658 1.4973248
## 44 63 71.74400 5.3442550 1.5994008
## 45 64 72.39134 5.3682887 1.6388299
## 46 65 73.08172 5.4387347 1.7818609
## 47 66 73.76203 5.4859732 1.8826557
## 48 67 74.42874 5.5059813 2.1246488
## 49 68 75.13082 5.5660930 2.4828869
## 50 69 75.80853 5.5266085 2.8138426
## 51 70 76.58968 5.6021126 3.1566056
## 52 71 77.31778 5.2885420 3.4334297
## 53 72 78.17632 5.2651465 3.8252552
## 54 73 79.13091 5.3383723 3.6885291
## 55 74 80.17216 4.8749758 3.9666176
## 56 75 81.48607 4.8123350 3.7167833
## 57 76 83.14663 4.7538824 3.4181805
## 58 77 85.48248 3.1143191 2.4744723
In what follows we display the linking relation obtained from the equipercentile method and compare it to that from the fixed-parameter calibration method.
plot(
rsss_fixedpar$`2`$raw_2,
rsss_fixedpar$`2`$tscore,
xlab = "CES-D Summed Score",
ylab = "PROMIS Depression T-score",
type = "l", col = "blue")
lines(
out_equate_tscore$concordance$raw_2,
out_equate_tscore$concordance$tscore_1,
lty = 2, col = "red")
grid()
legend(
"topleft",
c("Fixed-Parameter Calibration", "Equipercentile Linking"),
lty = 1:2, col = c("blue", "red"), bg = "white"
)
The linking results produced so far are now evaluated. More specifically, we assess how closely the CES-D summed scores linked to the PROMIS Depression T-scores match the actual PROMIS Depression T-scores observed in the present linking sample. Should we have set aside a validation sample, we would have performed this evaluation on that sample.
To begin with, we create an object scores
using
getScaleSum()
to contain raw summed scores on Scale 2
(i.e., CES-D). NA
will result for any respondents with one
or more missing responses on Scale 2. We could also create a summed
score variable for Scale 1 using the same function, e.g.,
getScaleSum(d, 1)
.
scores <- getScaleSum(d, 2)
head(scores)
## prosettaid raw_2
## 1 100048 21
## 2 100049 21
## 3 100050 24
## 4 100051 26
## 5 100052 20
## 6 100053 21
We obtain EAP estimates of theta on Scale 1 (i.e., PROMIS Depression)
based on item response patterns using the getTheta()
function. The first argument of the function is a data object of
PROsetta
class, which we created earlier with
loadData()
. The second argument specifies the item
parameter estimates to be used for the EAP estimation. Here, we use the
item parameter estimates previously obtained from the fixed-parameter
calibration, out_link_fixedpar$ipar_linked
. The third
argument scale = 1
specifies the scale to be scored (i.e.,
PROMIS Depression). These EAP estimates are based on the item responses
actually observed on PROMIS Depression and will serve as the reference
when we assess the CES-D scores liked to PROMIS Depression derived from
various methods.
eap_promis <- getTheta(d, out_link_fixedpar$ipar_linked, scale = 1)$theta
head(eap_promis)
## prosettaid theta_eap theta_se
## 1 100048 -0.42410653 0.1606312
## 2 100049 -1.15269342 0.3229802
## 3 100050 0.05281656 0.1176509
## 4 100051 -0.04622278 0.1238298
## 5 100052 -1.65063866 0.5049212
## 6 100053 -0.55824065 0.1812502
The EAP estimates for PROMIS Depression will be converted to T-scores using a linear transformation.
t_promis <- data.frame(
prosettaid = eap_promis$prosettaid,
t_promis = round(eap_promis$theta_eap * 10 + 50, 1)
)
head(t_promis)
## prosettaid t_promis
## 1 100048 45.8
## 2 100049 38.5
## 3 100050 50.5
## 4 100051 49.5
## 5 100052 33.5
## 6 100053 44.4
We then merge the PROMIS Depression T-scores with the raw summed scores for CES-D calculated in the previous step.
scores <- merge(scores, t_promis, by = "prosettaid")
head(scores)
## prosettaid raw_2 t_promis
## 1 100048 21 45.8
## 2 100049 21 38.5
## 3 100050 24 50.5
## 4 100051 26 49.5
## 5 100052 20 33.5
## 6 100053 21 44.4
Now we are going to generate T-scores linked to PROMIS Depression using only item responses on Scale 2 (CES-D). These T-scores linked to PROMIS Depression can be generated in different ways as:
The first two ways are based on the CES-D item parameters linked to the PROMIS Depression metric.
First, we get EAP estimates based on item response patterns on Scale
2 using the CES-D item parameters linked to the PROMIS Depression metric
(via fixed-parameter calibration). We then linearly transform the EAP
estimates to T-scores and add the T-scores (t_cesd_pattern
)
to the data frame object scores
.
eap_cesd <- getTheta(d, out_link_fixedpar$ipar_linked, scale = 2)$theta
t_cesd_pattern <- data.frame(
prosettaid = eap_cesd$prosettaid,
t_cesd_pattern = round(eap_cesd$theta_eap * 10 + 50, 1)
)
scores <- merge(scores, t_cesd_pattern, by = "prosettaid")
head(scores)
## prosettaid raw_2 t_promis t_cesd_pattern
## 1 100048 21 45.8 37.6
## 2 100049 21 38.5 37.6
## 3 100050 24 50.5 45.1
## 4 100051 26 49.5 48.5
## 5 100052 20 33.5 34.5
## 6 100053 21 44.4 37.6
Second, we use the raw-score-to-scale-score (RSSS) crosswalk table
obtained above using summed score EAP estimation to map each raw summed
score on Scale 2 onto a T-score on the PROMIS Depression metric,
t_cesd_rsss
.
rsss_eap <- data.frame(
raw_2 = rsss_fixedpar$`2`$raw_2,
t_cesd_rsss = round(rsss_fixedpar$`2`$tscore, 1)
)
scores <- merge(scores, rsss_eap, by = "raw_2")
head(scores)
## raw_2 prosettaid t_promis t_cesd_pattern t_cesd_rsss
## 1 20 101352 37.7 34.5 34.5
## 2 20 100621 54.6 34.5 34.5
## 3 20 104958 33.5 34.5 34.5
## 4 20 100059 38.9 34.5 34.5
## 5 20 104756 37.7 34.5 34.5
## 6 20 105375 37.6 34.5 34.5
Third, we use the concordance table from equipercentile linking to
map each raw summed score on Scale 2 onto a T-score on the PROMIS
Depression metric, t_cesd_eqp
.
rsss_eqp <- data.frame(
raw_2 = out_equate_tscore$concordance$raw_2,
t_cesd_eqp = round(out_equate_tscore$concordance$tscore_1, 1)
)
scores <- merge(scores, rsss_eqp, by = "raw_2")
head(scores)
## raw_2 prosettaid t_promis t_cesd_pattern t_cesd_rsss t_cesd_eqp
## 1 20 101352 37.7 34.5 34.5 33.6
## 2 20 100621 54.6 34.5 34.5 33.6
## 3 20 104958 33.5 34.5 34.5 33.6
## 4 20 100059 38.9 34.5 34.5 33.6
## 5 20 104756 37.7 34.5 34.5 33.6
## 6 20 105375 37.6 34.5 34.5 33.6
Finally, use compareScores()
to compare the obtained
T-scores.
# Reference score: IRT pattern scoring of Scale 1
c_pattern <- compareScores(
scores$t_promis, scores$t_cesd_pattern) ## IRT response pattern EAP to T-score
c_rsss <- compareScores(
scores$t_promis, scores$t_cesd_rsss) ## IRT summed score EAP to T-score
c_eqp <- compareScores(
scores$t_promis, scores$t_cesd_eqp) ## Equipercentile summed score to T-score
stats <- rbind(c_pattern, c_rsss, c_eqp)
rownames(stats) <- c("IRT Pattern", "IRT RSSS", "Equipercentile")
stats
## corr mean sd rmsd mad
## IRT Pattern 0.8437275 0.31409029 5.452607 5.461646 4.237209
## IRT RSSS 0.8212425 0.09425445 5.772118 5.772887 4.442818
## Equipercentile 0.8153648 -0.01121751 5.849425 5.849436 4.450889