R/GGUM2004.R

Defines functions run.GGUM2004 read.item.GGUM2004 read.person.GGUM2004 export.GGUM2004 write.GGUM2004

Documented in export.GGUM2004 read.item.GGUM2004 read.person.GGUM2004 run.GGUM2004 write.GGUM2004

#' @title Writes a command file for 'GGUM2004'
#'   
#' @description \code{write.GGUM2004} creates a 'GGUM2004' command file according 
#'   to the test characteristics. The file is saved in the 'GGUM2004' predefined 
#'   installation folder.
#'   
#' @param I The number of items.
#' @param C \eqn{C} is the number of observable response categories minus 1
#'   (i.e., the item scores will be in the set \eqn{\{0, 1, ..., C\}}{{0, 1,
#'   ..., C}}). It should either be a vector of \eqn{I} elements or a scalar. In
#'   the latter case it is assumed that \eqn{C} applies to all items.
#' @param cutoff Either a number or a vector of \eqn{I} elements which defines 
#'   the cutoff value. Default is 2.
#' @param model A string identifying the model. Possible values are "GUM" or 
#'   "GGUM" (default).
#' @param cmd.file A character string defining the name to give to the command 
#'   file. No file extension is required.
#' @param data.file A character string defining the name of the data file. No 
#'   file extension is required.
#' @param data.dir A character string defining the path to the directory where 
#' the data file (possibly exported by function 
#' \code{\link[GGUM]{export.GGUM2004}}) is stored. This also determines the 
#' directory where the command file generated by this function will be exported 
#' to. By default a temporary directory is used, but the user can naturally 
#' specify a directory of her choice.
#'   
#' @return A script file is saved in the directory where 'GGUM2004' is installed.
#'   
#' @section Details: This function prepares a 'GGUM2004' friendly command script,
#'   which may be used to run the 'GGUM2004' program (Roberts, Donoghue, &
#'   Laughlin, 2000; Roberts et al., 2006). 'GGUM2004' may be executed directly 
#'   or may be called from R, see \code{\link[GGUM]{run.GGUM2004}}.
#'   
#'   By default and for convenience, the command script is saved in the same 
#'   directory where the data file resides (\code{data.dir}). By experience, we 
#'   noticed that long directory paths (especially if spaces are included) make 
#'   'GGUM2004' fail to execute with error \code{file not found}. Therefore, a 
#'   good advice is to choose \code{data.dir} wisely (short paths, no spaces).
#'   
#'   Observe that this function is optimized for the Windows operating system 
#'   because 'GGUM2004' is a Windows program.
#'   
#' @references \insertRef{Robertsetal2000}{GGUM}
#' 
#' \insertRef{Robertsetal2006}{GGUM}
#' 
#' @author Sebastian Castro-Alvarez, \email{secastroal@gmail.com}
#'   
#' @examples
#' I <- 6
#' C <- c(3, 3, 3, 5, 5, 5)
#' write.GGUM2004(I, C, model = "GGUM")
#' 
#' @export
write.GGUM2004 <- function(I, C, cutoff = 2, model = "GGUM", 
                           cmd.file = "cmd", 
                           data.file = "data", 
                           data.dir = tempdir())
{
  # Sanity.OS() - OS:
  Sanity.OS()
  
  # Sanity check - C:
  Sanity.C(C, I)
  
  # Sanity check - C fixed:
  if (model == "GUM") Sanity.Cfixed(C)
  
  # Sanity check - model:
  Sanity.model(model)
  
  if (model == "GGUM") model <- 8 else model <- 3
  
  if (max(C) == min(C)) {
    ConstantC <- "Y"
    response  <- paste(C[1]+1, "NUMBER OF RESPONSE CATEGORIES")
  } else {
    ConstantC <- "N"
    response  <- C + 1
  }
  
  if (max(cutoff) == min(cutoff)) {
    ConstantCO <- "Y"
    responseCO <- paste(cutoff[1], "RESPONSE CUTOFF")
  } else {
    ConstantCO <- "N"
    responseCO <- cutoff
  }
  
  out<-list(paste(model, "ESTIMATE PARAMETERS OF MODEL", model),
            "N CONSTRAINTS ARE NOT USED",
            "N DO NOT CHANGE THE SIGN OF INITIAL PARAMETER ESTIMATES",
            "30 NUMBER OF QUADRATURE POINTS",
            paste0(data.dir, "/", data.file, ".txt"),
            paste0("(i4,1x,",I,"i2)"),
            paste(I,"NUMBER OF ITEMS"),
            paste(ConstantC,"IS NUMBER OF CATEGORIES CONSTANT?"),
            response,
            "N DO YOU WANT TO RECODE THE DATA?",
            paste(ConstantCO,"IS RESPONSE CUTOFF CONSTANT?"),
            responseCO,
            "N DISCARD ANY ITEMS",
            "N DISCARD ANY PEOPLE",
            "N SIGNS OF INITIAL LOCATION ESTIMATES NOT MANUALLY ASSIGNED",
            "100 NUMBER OF OUTER CYCLES",
            "50 NUMBER OF INNER CYCLES",
            "50 NUMBER OF FISHER SCORING ITERATIONS FOR THRESHOLDS",
            "50 NUMBER OF FISHER SCORING ITERATIONS FOR DELTAS & ALPHAS",
            "0.001 CRITERION",
            "N WANT TO PLOT",
            "N WANT FIT STATISTICS")
  
  address <- paste0(data.dir, "/", cmd.file, ".txt")
  if (file.exists(address)) file.remove(address)
  writeLines(unlist(out), con = address)
  
  cat("\n The command file '", cmd.file, ".txt' was saved to the directory '", 
      data.dir, "'.\n\n", sep = "")
}

#' @title Exports data in 'GGUM2004' friendly format
#'   
#' @description \code{export.GGUM2004} exports the data from R to a text file 
#'   according to the format required by 'GGUM2004'
#'   
#' @param data The R data matrix to be exported.
#' @param data.file A character string defining the name of the data file. No 
#'   file extension is required.
#' @param data.dir A character string defining the path to the directory where 
#' the data file (possibly exported by function 
#' \code{\link[GGUM]{export.GGUM2004}}) is stored. By default a temporary 
#' directory is used, but the user can naturally specify a directory of her 
#' choice.
#'   
#' @section Details: This function exports the R matrix \code{data} in 'GGUM2004'
#'   (Roberts, Donoghue, & Laughlin, 2000; Roberts et al., 2006) friendly
#'   format. This data file is to be used together with a 'GGUM2004' command
#'   script (or using the GUI itself, of course). 'GGUM2004' may be executed
#'   directly or may be called from R, see \code{\link[GGUM]{run.GGUM2004}}.
#'   
#'   By experience, we noticed that long directory paths (especially if spaces 
#'   are included) make 'GGUM2004' fail to execute with error 
#'   \code{file not found}. Therefore, a good advice is to choose 
#'   \code{data.dir} wisely (short paths, no spaces).
#'   
#'   Observe that this function is optimized for the Windows operating system 
#'   because 'GGUM2004' is a Windows program.
#'   
#' @references \insertRef{Robertsetal2000}{GGUM}
#' 
#' \insertRef{Robertsetal2006}{GGUM}
#' 
#' @author Jorge N. Tendeiro, \email{tendeiro@hiroshima-u.ac.jp}
#'   
#' @examples
#' # Generate data:
#' C   <- c(3, 3, 3, 5, 5, 5)
#' I   <- 6
#' gen <- GenData.GGUM(750, I, C, seed = 125)
#' # Export data to 'GGUM2004':
#' export.GGUM2004(gen$data)
#' 
#' @export
export.GGUM2004 <- function(data, data.file = "data", data.dir = tempdir()) 
{
  # Sanity.OS() - OS:
  Sanity.OS()
  
  # Sanity check - data:
  Sanity.data(data)
  
  N <- nrow(data)
  if (N > 2000) stop("GGUM2004 is limited to 2000 subjects or less. Aborted")
  
  I <- ncol(data)
  if (I > 100) stop("GGUM2004 is limited to 100 items or less. Aborted")
  
  if (max(data, na.rm = TRUE) > 9) {
    stop("GGUM2004 is limited to 10 response categories per item (coded 0,...,9) or less. Aborted")
  }
  
  data.export <- data
  data.export[is.na(data.export)] <- -9
  address <- paste0(data.dir, "/", data.file, ".txt")
  
  if (file.exists(address)) file.remove(address)
  
  for (n in 1:N) {
    data.str <- gsub(" -", "-", paste(data.export[n, ], collapse = " "))
    if (substr(data.str, 1, 1) == "-") {space <- " "} else {space <- "  "}
    if (n < 10)                  {write.table(paste(c("000", n, space, data.str), collapse = ""), address,
                                              col.names = FALSE, row.names = FALSE, sep = "", append = TRUE, quote = FALSE)}
    if ((n >= 10) & (n < 100))   {write.table(paste(c("00" , n, space, data.str), collapse = ""), address,
                                              col.names = FALSE, row.names = FALSE, sep = "", append = TRUE, quote = FALSE)}
    if ((n >= 100) & (n < 1000)) {write.table(paste(c("0"  , n, space, data.str), collapse = ""), address,
                                              col.names = FALSE, row.names = FALSE, sep = "", append = TRUE, quote = FALSE)}
    if (n >= 1000)               {write.table(paste(c(       n, space, data.str), collapse = ""), address,
                                              col.names = FALSE, row.names = FALSE, sep = "", append = TRUE, quote = FALSE)}
  }
  
  cat("\n The data file '", data.file, ".txt' was saved to the directory '", 
      data.dir, "'.\n\n", sep = "")
}

#' @title Read 'GGUM2004' person estimates into R
#'   
#' @description \code{read.person.GGUM2004} reads the output files from 'GGUM2004'
#'   with the person parameters. Both the person parameter estimates and their 
#'   standard errors are imported into R.
#'   
#' @param temp.dir The directory where 'GGUM2004' saved the output. By default, it
#'   is "C:/GGUM2004/TEMPFILE".
#' @param precision Number of decimal places of the results (default = 4).
#'   
#' @return An \eqn{N\times 3}{Nx3} matrix is returned, where \eqn{N} is the 
#'   number of persons. The first column is the person ID, the second column has
#'   the person parameter estimates, and the last column has the standard
#'   errors.
#'   
#' @section Details: Observe that this function is optimized for the Windows
#'   operating system because 'GGUM2004' is a Windows program.
#'   
#' @references \insertRef{Robertsetal2006}{GGUM}
#' 
#' @author Sebastian Castro-Alvarez, \email{secastroal@gmail.com}
#'   
#' @examples
#' \dontrun{
#' # If the 'GGUM2004' output files are in the default directory 
#' # (C:/GGUM2004/TEMPFILE), then simply execute
#' read.person.GGUM2004()
#' }
#' @export
read.person.GGUM2004 <- function(temp.dir = "C:/GGUM2004/TEMPFILE", 
                                 precision = 4)
{
  # Sanity.OS() - OS:
  Sanity.OS()
  
  # Retrieve N:
  # N used in computations:
  tmp <- readLines(paste0(temp.dir, "/FT14F001"))
  tmp <- trimws(tmp)
  tmp <- gsub("^ *|(?<= ) | *$", "", tmp, perl = TRUE) # merge spaces
  tmp <- as.numeric(unlist(strsplit(tmp, " ")))
  N.used   <- tmp[1]
  rm(tmp)
  # N discarded:
  tmp <- readLines(paste0(temp.dir, "/FT06F001"))
  pos <- which(grepl("SUBJECTS WERE DISCARDED ON DATA CLEAN-UP", tmp))
  tmp <- tmp[pos]
  tmp <- trimws(tmp)
  tmp <- unlist(strsplit(tmp, " "))
  N.disc   <- as.numeric(tmp[1])
  N.disc <- ifelse(is.integer(N.disc), N.disc, 0)
  rm(tmp)
  # 
  N <- N.used + N.disc
  
  GGUM.file <- readLines(paste0(temp.dir, "/FT17F001"))
  GGUM.file <- gsub("=", "= ", GGUM.file)
  GGUM.file <- gsub("#", "", GGUM.file)
  GGUM.file <- gsub("************", "NaN", GGUM.file, fixed = TRUE)
  th        <- grep(pattern = "THETA", GGUM.file)
  theta     <- read.table(textConnection(GGUM.file[th]))
  
  out           <- matrix(NA, N, 3)
  out[, 1]      <- 1:N
  colnames(out) <- c("Person", "Theta","Theta.SE")
  for(i in 1:N){
    if (i %in% theta$V2)
    {
      pos         <- which(theta$V2 == i)
      out[i, 2:3] <- unlist(theta[pos, c(4, 6)])
    }
  }
  
  return(round(out, precision))
}

#' @title Read 'GGUM2004' item estimates into R
#'   
#' @description \code{read.item.GGUM2004} reads the output files from 'GGUM2004' 
#'   with the item parameters. Both the item parameter estimates and their 
#'   standard errors are imported into R.
#'   
#' @param temp.dir The directory where 'GGUM2004' saved the output. By default, it
#'   is "C:/GGUM2004/TEMPFILE".
#' @param precision Number of decimal places of the results (default = 4).
#'   
#' @return \code{read.item.GGUM2004} returns a list cointaning the following 
#'   components: \item{alpha}{The estimated discrimination parameters
#'   (for GGUM).} \item{delta}{The estimated difficulty parameters.} 
#'   \item{taus}{The estimated threshold parameters.} \item{alphaSE}{The
#'   standard errors for the estimated discrimination parameters (for GGUM).} 
#'   \item{deltaSE}{The standard errors for the estimated difficulty 
#'   parameters.} \item{tausSE}{The standard errors for the estimated threshold 
#'   parameters (above zero; recall that the threshold parameters are
#'   constrained to symmetry around zero, that is, 
#'   \eqn{\tau_{i(C+1)}=0}{tau_{i(C+1)} = 0} and 
#'   \eqn{\tau_{iz}=-\tau_{i(M-z+1)}}{tau_{iz} = -tau_{i(M-z+1)}} for 
#'   \eqn{z\not= 0}{z != 0}.}
#'   
#' @section Details: Observe that this function is optimized for the Windows
#'   operating system because 'GGUM2004' is a Windows program.
#'   
#' @references \insertRef{Robertsetal2000}{GGUM}
#' 
#' \insertRef{Robertsetal2006}{GGUM}
#' 
#' @author Sebastian Castro-Alvarez, \email{secastroal@gmail.com}
#'   
#' @examples
#' \dontrun{
#' # If the 'GGUM2004' output files are in the default directory 
#' # (C:/GGUM2004/TEMPFILE), then simply execute
#' read.item.GGUM2004()
#' }
#' @export
read.item.GGUM2004 <- function(temp.dir = "C:/GGUM2004/TEMPFILE", 
                               precision = 4)
{
  # Sanity.OS() - OS:
  Sanity.OS()
  
  # Retrieve I:
  tmp <- readLines(paste0(temp.dir, "/FT14F001"))
  tmp <- trimws(tmp)
  tmp <- gsub("^ *|(?<= ) | *$", "", tmp, perl = TRUE) # merge spaces
  tmp <- as.numeric(unlist(strsplit(tmp, " ")))
  I   <- tmp[2]
  rm(tmp)
  
  # Retrieve C:
  tmp <- readLines(paste0(temp.dir, "/FT06F001"))
  pos <- which(grepl("EACH ITEM HAS", tmp))
  if (length(pos) > 0) # If C is fixed
  {
    tmp <- tmp[pos]
    tmp <- trimws(tmp)
    tmp <- gsub("^ *|(?<= ) | *$", "", tmp, perl = TRUE) # merge spaces
    tmp <- unlist(strsplit(tmp, " "))
    C   <- as.numeric(tmp[4]) - 1
    C   <- rep(C, I)
    rm(tmp)
  } else # If C varies
  {
    rm(tmp)
    tmp <- readLines(paste0(temp.dir, "/FT16F001"))
    tmp <- gsub("=", "= ", tmp)
    tmp <- gsub("************", "NaN", tmp, fixed = TRUE) # For when GGUM2004 
                                                          # doesn't converge.
    tmp <- read.table(text = tmp, skip = 4, header = FALSE, comment.char = "", 
                      fill = TRUE)
    pos <- which(grepl("ITEM#", tmp$V1))
    pos <- c(pos, nrow(tmp) + 1)
    C   <- diff(pos) - 2
    rm(tmp)
  }
  
  # Retrieve model:
  tmp <- readLines(paste0(temp.dir, "/FT06F001"))
  pos <- which(grepl("MARGINAL LOG-LIKELIHOOD FOR MODEL", tmp))
  tmp <- tmp[pos]
  tmp <- gsub(".*=", "", tmp)
  tmp <- trimws(tmp)
  tmp <- unlist(strsplit(tmp, " "))
  if (as.numeric(tmp[1]) == 3) model <- "GUM" else model <- "GGUM"
  rm(tmp)
 
  # Clean up GGUM2004 output item's parameters file:
  GGUM.file <- readLines(paste0(temp.dir, "/FT16F001"))
  GGUM.file <- gsub("=", "= ", GGUM.file)
  GGUM.file <- gsub("************", "NaN", GGUM.file, fixed = TRUE) # For when 
                                                   # GGUM2004 doesn't converge.
  it.est  <- read.table(text = GGUM.file, skip = 4, header = FALSE, 
                        comment.char = "", fill = TRUE)
  it.est  <- split(it.est, it.est$V1)
  delta   <- it.est$`ITEM#`[, 6]
  deltaSE <- it.est$`ITEM#`[, 8]
  if (model == "GGUM")
  {
    alpha   <- it.est$`ITEM#`[, 10]
    alphaSE <- it.est$`ITEM#`[, 12]
  }
  
  Cplus1    <- C+1
  threshold   <- it.est$`THRESHOLD#`[, 6]
  thresholdSE <- it.est$`THRESHOLD#`[, 8]
  if (model == "GUM")
  {
    taushalf   <- matrix(rep(threshold[2:max(Cplus1)], I), nrow = I, 
                         ncol = max(C), byrow = TRUE)
    taushalfSE <- matrix(rep(thresholdSE[2:max(Cplus1)], I), nrow = I, 
                         ncol = max(C), byrow = TRUE)
    taus       <- cbind(taushalf, rep(0, I), taushalf[, max(C):1]*(-1))
    tausSE     <- taushalfSE[, max(C):1]
    
    return(list("delta"   = round(delta, precision), 
                "taus"    = round(taus, precision),
                "deltaSE" = round(deltaSE, precision), 
                "tausSE"  = round(tausSE, precision)))
  }
  else
  {
    taushalf        <- matrix(NA, nrow = I, ncol = max(C))
    taushalfSE      <- taushalf
    taushalf[1, ]   <- c(rep(0, max(C)- C[1]), threshold[2:Cplus1[1]])
    taushalfSE[1, ] <- c(rep(0, max(C)- C[1]), thresholdSE[2:Cplus1[1]])
    for (i in 2:I)
    {
      taushalf[i, ]   <- c(rep(0, max(C)- C[i]), 
                           threshold[(sum(Cplus1[1:(i-1)]) + 2):sum(Cplus1[1:i])])
      taushalfSE[i, ] <- c(rep(0, max(C)- C[i]), 
                           thresholdSE[(sum(Cplus1[1:(i-1)]) + 2):sum(Cplus1[1:i])])
    }
    taus   <- cbind(taushalf, rep(0, I), taushalf[, max(C):1]*(-1))
    tausSE <- taushalfSE[, max(C):1]
    
    return(list("alpha"   = round(alpha, precision), 
                "delta"   = round(delta, precision), 
                "taus"    = round(taus, precision),
                "alphaSE" = round(alphaSE, precision), 
                "deltaSE" = round(deltaSE, precision), 
                "tausSE"  = round(tausSE, precision)))
  }
}


#' @title Call 'GGUM2004' and import the estimated parameters into R
#'   
#' @description \code{run.GGUM2004} executes a previously exported 'GGUM2004' 
#'   command file (via function \code{\link[GGUM]{write.GGUM2004}}). It returns 
#'   the execution time, the item parameter estimates, and the person parameter 
#'   estimates.
#'   
#' @param cmd.file A character string defining the name of the command file. No 
#'   file extension is required.
#' @param data.file A character string defining the name of the data file. No 
#'   file extension is required.
#' @param datacmd.dir A character string defining the path to the directory 
#' where both the data file (identified by the \code{data.file} parameter and 
#' exported by function \code{\link[GGUM]{export.GGUM2004}}) and the command 
#' file (identified by the \code{cmd.file} parameter and 
#' exported by function \code{\link[GGUM]{write.GGUM2004}}) are saved.
#' @param prog.dir A character string defining the directory where 'GGUM2004' is 
#'   installed (default: "C:/GGUM2004").
#' @param precision Number of decimal places of the results (default = 4).
#'   
#' @return \code{run.GGUM2004} returns a list cointaning the following 
#'   components: \item{time}{The 'GGUM2004' execution time.} 
#'   \item{alpha}{The estimated discrimination parameters (for GGUM).} 
#'   \item{delta}{The estimated difficulty parameters.} \item{taus}{The
#'   estimated threshold parameters.} \item{SE}{The standard errors for the
#'   estimated item parameters.} \item{theta}{The estimated person parameters
#'   and their standard errors.} 
#'   
#' @section Details: Function \code{run.GGUM2004} runs internally both functions
#'   \code{\link[GGUM]{read.item.GGUM2004}} (to import the 'GGUM2004' item 
#'   estimates into R) and \code{\link[GGUM]{read.person.GGUM2004}} (to import 
#'   the 'GGUM2004' person estimates into R).
#'   
#'   By experience, we noticed that long directory paths (especially if spaces 
#'   are included) make 'GGUM2004' fail to execute with error 
#'   \code{file not found}. Therefore, a good advice is to choose 
#'   \code{datacmd.dir} and \code{prog.dir} wisely (short paths, no spaces).
#'   
#'   Observe that this function is optimized for the Windows operating system 
#'   because 'GGUM2004' is a Windows program.
#'   
#' @references \insertRef{Robertsetal2006}{GGUM}
#' 
#' @author Sebastian Castro-Alvarez, \email{secastroal@gmail.com}
#'   
#' @examples
#' \dontrun{
#' # Generate data:
#' C   <- c(3, 3, 3, 5, 5, 5)
#' I   <- 6
#' gen <- GenData.GGUM(750, I, C, seed = 125)
#' # Export data to 'GGUM2004':
#' export.GGUM2004(gen$data)
#' # Write command file:
#' write.GGUM2004(I, C, model = "GGUM")
#' # Run 'GGUM2004':
#' res.GGUM2004 <- run.GGUM2004()
#' }
#' @export
run.GGUM2004 <- function(cmd.file = "cmd", 
                         data.file = "data", 
                         datacmd.dir = tempdir(), 
                         prog.dir = "C:/GGUM2004", 
                         precision = 4)
{
  # Sanity.OS() - OS:
  Sanity.OS()
  
  # Check if cmd.file exists:
  if (!file.exists(paste0(datacmd.dir, "/" , cmd.file, ".txt")))
  {
    stop(paste0('The GGUM2004 command file is not available. Please export it to 
         directory ', dir, ' using function write.GGUM2004(). Aborted.'))
  }
  
  # Check if data.file exists:
  if (!file.exists(paste0(datacmd.dir, "/" , data.file, ".txt")))
  {
    stop(paste0('The data file for GGUM2004 is not available. Please export it to 
         directory ', dir, ' using function export.GGUM2004(). Aborted.'))
  }
  
  # Check if GGUM2004 is installed in dir:
  if (!file.exists(paste0(prog.dir, "/ggumnsf.exe")))
  {
    stop(paste0('GGUM2004 does not seem to be installed in the directory ', dir, '. 
                Aborted.'))
  }
  
  # Prepare dir/TEMPFILE to store the outputs from GGUM2004:
  tempfolder <- paste(prog.dir ,"TEMPFILE", sep = "/")
  if (!dir.exists(tempfolder)) dir.create(tempfolder)
  file.remove(dir(tempfolder, full.names = TRUE))
  
  cmd <- paste(paste(prog.dir ,"ggumnsf", sep="/"), 
               paste0(datacmd.dir, "/", cmd.file, ".txt"), 
               tempfolder)
  
  # Run GGUM2004:
  cat("\n")
  t0 <- proc.time()
  system(cmd)
  t1 <- proc.time()
  
  # Retrieve I, N, C, model from files:
  tmp <- readLines(paste0(datacmd.dir, "/", data.file, ".txt"))
  I <- (nchar(tmp[1]) - 5) / 2
  N <- length(tmp)
  rm(tmp); 
  tmp <- readLines(paste0(datacmd.dir, "/", cmd.file, ".txt"))
  pos <- which(grepl("Y IS NUMBER OF CATEGORIES CONSTANT?", tmp))
  if (length(pos) > 0) 
  {
    C <- as.numeric(substr(tmp[pos+1], 1, 1)) - 1
  } else {
    pos1 <- which(grepl("N IS NUMBER OF CATEGORIES CONSTANT?", tmp))
    pos2 <- which(grepl("N DO YOU WANT TO RECODE THE DATA?", tmp))
    C    <- as.numeric(tmp[(pos1+1):(pos2-1)]) - 1
  }
  C.max <- max(C)
  # 
  tmp <- tmp[1]
  tmp <- trimws(tmp)
  tmp <- unlist(strsplit(tmp, " "))
  if (as.numeric(tmp[1]) == 3) model <- "GUM" else model <- "GGUM"
  rm(tmp)
  
  # Retrieve item parameters and SEs:
  items <- read.item.GGUM2004(tempfolder, precision)
  theta <- read.person.GGUM2004(tempfolder, precision)
  
  if (model == "GUM")
  {
    SE.out <- cbind(items$deltaSE, items$tausSE)
    colnames(SE.out) <- c("SE.delta", paste0("SE.tau", 1:C.max))
    return(list("time" = t1 - t0, "delta" = items$delta,
                "taus" = items$taus, "SE" = SE.out, 
                "theta" = theta))
  }
  
  if (model == "GGUM")
  {
    SE.out <- cbind(items$alphaSE, items$deltaSE, items$tausSE)
    colnames(SE.out) <- c("SE.alpha", "SE.delta", paste0("SE.tau", 1:C.max))
    return(list("time" = t1 - t0, 
                "alpha" = items$alpha, "delta" = items$delta,
                "taus" = items$taus, "SE" = SE.out, 
                "theta" = theta))
  }
}
jorgetendeiro/GGUM documentation built on Sept. 12, 2023, 3:12 p.m.