Introduction to conquestr

Dan Cloney

2024-07-24

conquestr has three main functions:

These functions allows users to include ‘ACER ConQuest’ within their R workflow. This is particularly useful for users of the Mac OS X version (and Windows console) version of ‘ACER ConQuest’ which does not support ploting.

This vignette demonstrates how to use the package built-in demonstration files to:

Call ConQuest and run a syntax file

First, ensure you have the most current version of ConQuest. Version > 5.17.4 is required. If you are unsure, check ConQuest on the ACER Shop. You will also need to install the conquestr library:

install.packages("conquestr")
library("conquestr")

You must pass the ConQuestCall function at least two pieces of information: the install location of ConQuest and a valid syntax file. conquestr has included syntax files that can be used to run a model and test other package functions. A default syntax file will be called is you do not explicitly provide one. conquestr will search for a valid installation of ‘ACER ConQuest’ unless the executable is explicitly declared. The search locations are (in order):

# if you don't provide a syntax file, using the argumenmt `cqc=`, then the in-built demo syntax file will be run. 
ConQuestCall() 
# the following output is produced:

ConQuest build: Mar 10 2021
<TYPE> Version
This version expires <DATE>
submit <PATH>conquestr/extdata/conquestabout.cqc;
=>dir;
<PATH>
=>about;
Developed by
    Australian Council for Educational Research
    University of California,Berkeley

Your key: <KEY>
Expires: <DATE>

<TYPE> Build:  <DATE>
Version: 5.17.4

Programmers
    Ray Adams,Margaret Wu,Greg Macaskill,Sam Haldane,Xiao Xun Sun,Dan Cloney
End of Program

When you use ConQuestCall to call ‘ACER ConQuest’ and run a syntax file, some options are set by default. The same options can be set within ‘ACER ConQuest’ by using the set command (set progress = yes, exit_on_error = yes, storecommands = yes, warnings = no; which is syntactically the same as using the helper function set conquestr = true;). WARNING - this will make it easy to overwrite output as you will not be prompted or warned. To turn off these settings your syntax file must explicitly change these using the set command. For more information see the set command.

When calling ‘ACER ConQuest’ from R, the ConQuest working directory will default to the current R working directory. This makes it easy to write portable syntax using relative paths. If you need ‘ACER ConQuest’ to use a different working directory, set it in your syntax file.

The next example runs a small analysis and creates a system file that is read into the R object myExSys.

# set up
oldWd <- getwd()
myTmpDir <- tempdir()
setwd(myTmpDir)
file.copy(from = c(
  system.file("extdata", "ex1.cqc", package = "conquestr"),
  system.file("extdata", "ex1.dat", package = "conquestr"),
  system.file("extdata", "mysysfile.cqs", package = "conquestr")
  ), to = myTmpDir)
#> [1] TRUE TRUE TRUE

# run ConQuest
# ConQuestCall is not run here, as it requires a local install of ConQuest 
# ConQuestCall(cqc = file.path(myTmpDir, "ex1.cqc"), stdout = NULL) # searches for valid install of CQ
myExSys <- ConQuestSys(myCqs = file.path(myTmpDir, "mysysfile.cqs"))

# see the content of the sysfile
str(myExSys)
#> List of 211
#>  $ compressedString       : chr "uncompressed"
#>  $ builddate              : chr "Jul 23 2024"
#>  $ writedate              : chr "Tue Jul 23 15:06:15 2024\n"
#>  $ cqs_version            : int 26
#>  $ gNCases                :List of 11
#>   ..$ : num 1000
#>   ..$ : num 1000
#>   ..$ : num 1000
#>   ..$ : num 1000
#>   ..$ : num 999
#>   ..$ : num 75
#>   ..$ : num 925
#>   ..$ : num 1000
#>   ..$ : num 999
#>   ..$ : num 925
#>   ..$ : num 1000
#>  $ gNDim                  : int 1
#>  $ gNGins                 : int 12
#>  $ gNPlausiblesEstimate   : int 5
#>  $ gMLEExist              : logi TRUE
#>  $ gWLEExist              : logi TRUE
#>  $ gEAPExist              : logi TRUE
#>  $ gPlausibleExist        : logi TRUE
#>  $ gSystemMissing         : num -1.8e+308
#>  $ gApplyFilter           : logi FALSE
#>  $ gFilter                :List of 4
#>   ..$ String : logi [1, 1] NA
#>   ..$ Items  : int 0
#>   ..$ Columns: int 0
#>   ..$ Size   : int 0
#>  $ gBeta                  : num [1, 1] 0
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gOldBeta               : num [1, 1] 0
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gBestBeta              : num [1, 1] 0
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gXsi                   : num [1:12, 1] -0.704 -1.251 -1.092 -0.231 0.111 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:12] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gOldXsi                : num [1:12, 1] -0.704 -1.251 -1.092 -0.231 0.111 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:12] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gBestXsi               : num [1:12, 1] -0.704 -1.251 -1.092 -0.231 0.111 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:12] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gTau                   : logi [1, 1] NA
#>  $ gOldTau                : logi [1, 1] NA
#>  $ gBestTau               : logi [1, 1] NA
#>  $ gQuickErrorsXsi        : num [1:12, 1] 0.00513 0.00605 0.00572 0.00479 0.00476 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:12] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gQuickErrorsTau        : logi [1, 1] NA
#>  $ gQuickErrorsSigma      : num [1, 1] 0.0015
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gQuickErrorsBeta       : num [1, 1] 0.000866
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gMasterTheta           : num [1:2000, 1] 0.69 0.679 0.89 0.15 -0.626 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:2000] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gTheta                 : num [1:2000, 1] 0.455 0.445 0.641 -0.047 -0.769 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:2000] "" "" "" "" ...
#>   .. ..$ : chr ""
#>  $ gVariance              : num [1, 1] 0.865
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gOldVariance           : num [1, 1] 0.865
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gBestVariance          : num [1, 1] 0.865
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gHistoWeights          : logi [1, 1] NA
#>  $ gOldHisto              : logi [1, 1] NA
#>  $ gBestHisto             : logi [1, 1] NA
#>  $ gYBeta                 : num [1, 1] 0
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gWtFactor              :List of 4
#>   ..$ : num 1
#>   ..$ : num 1
#>   ..$ : num 1
#>   ..$ : num 1
#>  $ gSuffXsi               : num [1:12, 1] -644 -743 -716 -548 -476 -764 -776 -766 -852 -776 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : NULL
#>   .. ..$ : chr ""
#>  $ gSuffTau               : logi [1, 1] NA
#>  $ gModelText             : chr "item"
#>  $ gFormatText            : chr " pid 1-5 responses 12-23 v1 12 v2 15"
#>  $ gRegressionText        : chr ""
#>  $ gGroupText             : chr "v1"
#>  $ gOSSCP                 : num [1, 1] 999
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr ""
#>   .. ..$ : chr ""
#>  $ gLOSSCP                : logi [1, 1] NA
#>  $ gLSSCP                 : logi [1, 1] NA
#>  $ gFullSSCP              : logi [1, 1] NA
#>  $ gFullSums              : logi [1, 1] NA
#>  $ gMinAlpha              : num 0
#>  $ gModelEstimated        : logi TRUE
#>  $ gIntegrationMethod     :'data.frame': 7 obs. of  2 variables:
#>   ..$ gIntegrationMethod    : int [1:7] 1 2 3 4 5 6 7
#>   ..$ gIntegrationMethodText: chr [1:7] "Bock Aitkin" "Monte Carlo" "Gauss-Hermite Quadrature" "Joint Maximum Likelihood" ...
#>  $ gPopulation            : int 1
#>  $ gSeeds                 : int 5
#>  $ gMaxSinceBests         : int 100
#>  $ gInnerLoopss           : int 10
#>  $ gWarningss             : logi TRUE
#>  $ gEstsToLog             : logi TRUE
#>  $ gKeepLast              : logi FALSE
#>  $ gAddExtension          : logi TRUE
#>  $ gMLEMax                : num 15
#>  $ gPlotWinMax            : int 100
#>  $ gZero                  : num 0.3
#>  $ gRespMiss              : int 2
#>  $ gDatafileName          : chr "ex1.dat"
#>  $ gDatafileFormats       : int 0
#>  $ gDatafileNameDisplay   : chr "ex1.dat"
#>  $ gStopReason            : int 2
#>  $ gImplicit              :List of 2
#>   ..$ Name  :List of 1
#>   .. ..$ : chr "item"
#>   ..$ Levels:List of 1
#>   .. ..$ : int 12
#>  $ gNImpValue             : int 12
#>  $ gPIDVar                : int 0
#>  $ gModelVariables        :List of 2
#>   ..$ XV: list()
#>   ..$ IV:List of 1
#>   .. ..$ : int 0
#>  $ gNRec                  : int 1
#>  $ gResponseLookUp        :List of 2
#>   ..$ VarNumber: int -2
#>   ..$ Value    :List of 2
#>   .. ..$ : chr "0"
#>   .. ..$ : chr "1"
#>  $ gPreKeyLookUp          :List of 2
#>   ..$ VarNumber: int -2
#>   ..$ Value    :List of 6
#>   .. ..$ : chr "M"
#>   .. ..$ : chr "a"
#>   .. ..$ : chr "b"
#>   .. ..$ : chr "c"
#>   .. ..$ : chr "d"
#>   .. ..$ : chr "e"
#>  $ gNDataRecords          : int 11989
#>  $ gFacetVariables        :List of 2
#>   ..$ XV: list()
#>   ..$ IV: list()
#>  $ gRegressionVariables   :List of 2
#>   ..$ XV: list()
#>   ..$ IV: list()
#>  $ gGroupVariables        :List of 2
#>   ..$ XV:List of 1
#>   .. ..$ : int 1
#>   ..$ IV: list()
#>  $ gWeightVariable        :List of 2
#>   ..$ XV: list()
#>   ..$ IV: list()
#>  $ gTDFileV               :List of 2
#>   ..$ XV: list()
#>   ..$ IV:List of 1
#>   .. ..$ : int 0
#>  $ gValidC                : list()
#>  $ gFileRebuildNeeded     : logi FALSE
#>  $ gAMatrixImportFileName : chr ""
#>  $ gCMatrixImportFileName : chr ""
#>  $ gHistoryFileName       : chr ""
#>  $ gTitle                 : chr "ConQuest: Generalised Item Response Modelling Software"
#>  $ gStoreInRAM            : logi FALSE
#>  $ gSubmitMode            : logi TRUE
#>  $ gMaxCats               : int 2
#>  $ gConvergenceOK         : logi FALSE
#>  $ gParameterConvCriterion: num 1e-04
#>  $ gDevianceConvCriterion : num 1e-04
#>  $ gFitDraws              : int 5
#>  $ gMaxIterations         : int 1000
#>  $ gAccuracy              : int 15
#>  $ gPVNodes               : int 2000
#>  $ gFitNodes              : int 2000
#>  $ gIteration             : int 23
#>   [list output truncated]
#>  - attr(*, "class")= chr [1:2] "list" "conQuestSysFile"

# tidy up
file.remove(
  list.files(myTmpDir, all.files = TRUE, full.names = TRUE, pattern = "^myi|^myS|ex1"),
  recursive=TRUE
)
#> [1] TRUE TRUE
setwd(oldWd)

Read in a ConQuest system file

The above example created a system file. Alternatively, there is an inbuilt example of a system file.

conquestr can read in a system file, using the ConQuestSys function. This function returns a list that includes the response data, parameter estimates, and other data objects created by ‘ACER ConQuest’. These lists can be optionally coerced into R data frames.

# if no argument is provided to ConQuestSys, the example system file is read in by default.
myCqs <- ConQuestSys()
#> no system file provided, loading the example system file instead

You can see the data objects available within the object (e.g., str(myCqs)), and some useful objects will be:

Users can search the names of objects in the system file using the helper function searchConQuestSys:

# search for objects named history in myCqs
searchConQuestSys("history", myCqs)
#> [1] "gHistoryFileName" "gHistory"         "gCommandHistory"