Skip to content

Commit 41b4f01

Browse files
author
Wenchao-Ma
committed
2.0.8
1 parent 2afa5b2 commit 41b4f01

File tree

9 files changed

+57
-40
lines changed

9 files changed

+57
-40
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: GDINA
22
Type: Package
33
Title: The Generalized DINA Model Framework
4-
Version: 2.0.5
5-
Date: 2018-3-26
4+
Version: 2.0.8
5+
Date: 2018-3-28
66
Authors@R: c(person(given = "Wenchao",family = "Ma", role = c("aut", "cre", "cph"),email = "wenchao.ma@ua.edu"),person(given = "Jimmy", family = "de la Torre", role = c("aut", "cph")), person(given="Miguel",family = "Sorrel",role = "ctb"))
77
Description: A set of psychometric tools for cognitive diagnosis modeling for both dichotomous and polytomous responses. Various cognitive diagnosis models can be estimated, include the generalized deterministic inputs, noisy and gate (G-DINA) model by de la Torre (2011) <DOI:10.1007/s11336-011-9207-7>, the sequential G-DINA model by Ma and de la Torre (2016) <DOI:10.1111/bmsp.12070>, and many other models they subsume. Joint attribute distribution can be independent, saturated, higher-order, loglinear smoothed or structured. Q-matrix validation, item and model fit statistics, model comparison at test and item level and differential item functioning can also be conducted. A graphical user interface is also provided.
88
License: GPL-3

NEWS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# GDINA 2.0.-
2-
* Fixed - bugs in C++ codes
1+
# GDINA 2.0.7
2+
* bug fixed
33

44
# GDINA 2.0
55
* This is a major update including a large number of new features. The `GDINA` function has been largely rewritten for both flexibility and speed.

R/Est.R

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Est <- function(dat, Q, model, sequential,att.dist, att.prior,saturated,
1919
myControl <- list(
2020
maxitr = 2000,
2121
conv.crit = 1e-4,
22-
conv.type = "max.ip.change",
22+
conv.type = c("ip","mp"),
2323
nstarts = 3L,
2424
lower.p = 1e-4,
2525
upper.p = 1 - 1e-4,
@@ -322,7 +322,6 @@ Est <- function(dat, Q, model, sequential,att.dist, att.prior,saturated,
322322
neg2LL <- NA
323323
}
324324
initial.parm <- item.parm
325-
parm0 <- list(ip = c(item.parm), prior = c(exp(logprior)), neg2LL = 0)
326325

327326

328327
##############################
@@ -332,11 +331,13 @@ Est <- function(dat, Q, model, sequential,att.dist, att.prior,saturated,
332331
#############################
333332
itr <- 0L
334333
delta <- calc_delta(item.parm, DesignMatrices = DesignMatrices, linkfunc = linkfunc)
335-
# parm0 <- item.parm
334+
335+
parm0 <- list(ip = c(item.parm), prior = c(exp(logprior)), neg2LL = 0, delt = unlist(delta))
336336

337337
dif.parm <- list(ip = 0,
338338
prior = 0,
339-
neg2LL = 0)
339+
neg2LL = 0,
340+
delt = 0)
340341
##############################
341342
#
342343
# E-M
@@ -369,7 +370,7 @@ Est <- function(dat, Q, model, sequential,att.dist, att.prior,saturated,
369370
auglag_args = auglag_args,solnp_args = solnp_args,nloptr_args = nloptr_args)
370371

371372
item.parm <- optims$item.parm
372-
delta <- c(optims$delta)
373+
delta <- optims$delta
373374

374375

375376
struc.parm <- structural.parm(AlphaPattern = AlphaPattern, no.mg = no.mg, logprior=estep$logprior,
@@ -394,26 +395,31 @@ Est <- function(dat, Q, model, sequential,att.dist, att.prior,saturated,
394395

395396
parm1 <- list(ip = c(item.parm),
396397
prior = c(exp(estep$logprior)),
397-
neg2LL = -2 * estep$LL)
398+
neg2LL = -2 * estep$LL,
399+
delt = unlist(delta))
398400

399401
dif.parm <- list(ip = max(abs(parm1$ip-parm0$ip),na.rm = TRUE),
400402
prior = max(abs(parm1$prior-parm0$prior),na.rm = TRUE),
401-
neg2LL = parm0$neg2LL-parm1$neg2LL)
403+
neg2LL = parm0$neg2LL-parm1$neg2LL,
404+
delt = max(abs(parm1$delt-parm0$delt),na.rm = TRUE))
402405

403406
parm0 <- parm1
404407
itr <- itr + 1
408+
maxchg <- 0
409+
if(any(tolower(control$conv.type)=="ip")) maxchg <- max(maxchg,dif.parm$ip)
410+
if(any(tolower(control$conv.type)=="delta")) maxchg <- max(maxchg,dif.parm$delt)
411+
if(any(tolower(control$conv.type)=="mp")) maxchg <- max(maxchg,dif.parm$prior)
412+
if(any(tolower(control$conv.type)=="neg2ll")) maxchg <- max(maxchg,abs(dif.parm$neg2LL))
405413

406414
if(verbose==1) {
407-
cat('\rIter =',itr,' Max. abs. change =',formatC(max(dif.parm$ip,dif.parm$prior),digits = 5, format = "f"),
415+
cat('\rIter =',itr,' Max. abs. change =',formatC(maxchg,digits = 5, format = "f"),
408416
' Deviance =',formatC(-2 * estep$LL,digits = 3, format = "f"),' ')
409417
}else if (verbose==2) {
410-
cat('Iter =',itr,' Max. abs. change =',formatC(max(dif.parm$ip,dif.parm$prior),digits = 5, format = "f"),
418+
cat('Iter =',itr,' Max. abs. change =',formatC(maxchg,digits = 5, format = "f"),
411419
' Deviance =',formatC(-2 * estep$LL,digits = 3, format = "f"),' \n')
412420
}
413421

414-
if((tolower(control$conv.type)=="dev.change"&abs(dif.parm$neg2LL)<control$conv.crit)|
415-
(tolower(control$conv.type)=="max.ip.change"&dif.parm$ip<control$conv.crit)|
416-
(tolower(control$conv.type)=="max.parm.change"&max(dif.parm$ip,dif.parm$prior)<control$conv.crit)) break
422+
if(maxchg < control$conv.crit) break
417423
}
418424

419425
logprior0 <- logprior # old log priors
@@ -456,13 +462,13 @@ if(!att.str){
456462
npar <- npar + K
457463
}
458464
}
459-
neg2LL=-2 * estep$LL
465+
neg2LL <- -2 * estep$LL
460466

461467
item.prob <- vector("list",J)
462468
initial.parm <- m2l(initial.parm)
463469
for (j in seq_len(J)){
464470
item.prob[[j]] <- item.parm[j,1:Lj[j]]
465-
names(initial.parm[[j]]) <- names(item.prob[[j]]) <- paste0("P(",apply(alpha2(Kj[j]),1,paste0,collapse = ""),")")
471+
names(initial.parm[[j]]) <- names(item.prob[[j]]) <- paste0("P(",apply(attributepattern(Kj[j]),1,paste0,collapse = ""),")")
466472
}
467473
postP <- exp(t(estep$logprior))
468474
pf <- LC.Prob <- uP(parloc,item.parm)
@@ -503,7 +509,7 @@ if(!att.str){
503509
expectedCorrect = estep$Rg, expectedTotal = estep$Ng,initial.parm = initial.parm),
504510
options = list(dat = originalData, Q = originalQ, Qm = Q, Qcm = Qcm, model = model,
505511
itr = itr, dif.LL = dif.parm$neg2LL,dif.p=dif.parm$ip,dif.prior=dif.parm$prior,
506-
att.dist=att.dist, higher.order=higher.order,att.prior = att.prior,
512+
att.dist=att.dist, higher.order=higher.order,att.prior = att.prior, latent.var = latent.var,
507513
mono.constraint = mono.constraint, item.names = item.names,group = group, gr = gr,
508514
att.str= att.str, seq.dat = dat, no.group = no.mg, group.label = gr.label,
509515
verbose = verbose, catprob.parm = catprob.parm,sequential = sequential,

R/GDINA.R

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#' the C-RUM (Hartz, 2002), a special case of the GDM (von Davier, 2008), and that the R-RUM
1515
#' is also known as a special case of the generalized NIDA model (de la Torre, 2011).
1616
#'
17-
#' In addition, users are allowed to specify design matrix and link function for each item and
17+
#' In addition, users are allowed to specify design matrix and link function for each item, and
1818
#' distinct models may be used in a single test for different items.
1919
#' The attributes can be either dichotomous or polytomous
2020
#' (Chen & de la Torre, 2013). Joint attribute distribution may be modelled using independent or saturated model,
@@ -212,9 +212,11 @@
212212
#' \item \code{maxitr} A vector for each item or nonzero category, or a scalar which will be used for all
213213
#' items or nonzero categories to specify the maximum number of EM cycles allowed. Default = 2000.
214214
#' \item \code{conv.crit} The convergence criterion for max absolute change in item parameters or deviance. Default = 0.0001.
215-
#' \item \code{conv.type} How is the convergence criterion evaluated? Can be \code{"max.ip.change"}, indicating
216-
#' the maximum absolute change in success probabilities, or \code{"dev.change"}, representing
217-
#' the absolute change in deviance.
215+
#' \item \code{conv.type} How is the convergence criterion evaluated? A vector with possible elements: \code{"ip"}, indicating
216+
#' the maximum absolute change in item success probabilities, \code{"mp"}, representing
217+
#' the maximum absolute change in mixing proportion parameters, \code{"delta"}, indicating the maximum absolute change in delta
218+
#' parameters or \code{neg2LL} indicating the absolute change in negative two times loglikeihood. Multiple criteria can be specified.
219+
#' If so, all criteria need to be met. Default = c("ip", "mp").
218220
#' \item \code{nstarts} how many sets of starting values? Default = 1.
219221
#' \item \code{lower.p} A vector for each item or nonzero category,
220222
#' or a scalar which will be used for all items or nonzero categories to specify the lower bound for success probabilities.
@@ -798,11 +800,11 @@
798800
#' # for comparison, use change in -2LL as convergence criterion
799801
#' # LCDM
800802
#' lcdm <- GDINA(dat = dat, Q = Q, model = "UDF", design.matrix = D,
801-
#' linkfunc = "logit", control=list(conv.type="dev.change"),solver="slsqp")
803+
#' linkfunc = "logit", control=list(conv.type="neg2LL"),solver="slsqp")
802804
#'
803805
#' # identity link GDINA
804806
#' iGDINA <- GDINA(dat = dat, Q = Q, model = "GDINA",
805-
#' control=list(conv.type="dev.change"),solver="slsqp")
807+
#' control=list(conv.type="neg2LL"),solver="slsqp")
806808
#'
807809
#' # compare two models => identical
808810
#' anova(lcdm,iGDINA)
@@ -822,11 +824,11 @@
822824
#' # for comparison, use change in -2LL as convergence criterion
823825
#' # RRUM
824826
#' logACDM <- GDINA(dat = dat, Q = Q, model = "UDF", design.matrix = D,
825-
#' linkfunc = "log", control=list(conv.type="dev.change"),solver="slsqp")
827+
#' linkfunc = "log", control=list(conv.type="neg2LL"),solver="slsqp")
826828
#'
827829
#' # identity link GDINA
828830
#' RRUM <- GDINA(dat = dat, Q = Q, model = "RRUM",
829-
#' control=list(conv.type="dev.change"),solver="slsqp")
831+
#' control=list(conv.type="neg2LL"),solver="slsqp")
830832
#'
831833
#' # compare two models => identical
832834
#' anova(logACDM,RRUM)

R/Mstep.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ opts <- list()
1313
ConstrMatrix=ConstrMatrix[[j]],linkfunc=linkfunc[j],eps=1e-16,ConstrType=ConstrType[j])
1414
if(is.null(optims)) stop(paste("M-step fails for item",j,"at iteration",itr),call. = FALSE)
1515

16-
delta[[j]] <- optims$delta
16+
delta[[j]] <- c(optims$delta)
1717
item.parm[j,1:(2^Kj[j])] <- optims$phat
1818
opts[[j]] <- optims
1919
}

R/extract.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ extract.GDINA <- function(object,what,SE.type = 2,...){
286286
item.names = object$options$item.names,
287287
itemprob.history = object$diagnos$itemprob.matrix,
288288
Kj = {rowSums(extract(object,"Q"))},
289+
latent.var = object$options$latent.var,
289290
LCprob.parm = object$LC.prob,
290291
LCpf.parm = {
291292
LCpf <- patt <- eta(as.matrix(extract(object,"Q")))

R/print.GDINA.R

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ print.GDINA <-
2222
# cat("\n-----------------------------------------------\n")
2323
cat("Model")
2424
cat("\n-----------------------------------------------\n")
25-
cat("Fitted model(s) =", unique(extract.GDINA(x,"models")), "\n")
25+
lv <- NULL
26+
if(extract(x,"latent.var")=="bugs"){
27+
lv <- "Bug"
28+
}
29+
cat("Fitted model(s) =", lv,unique(extract.GDINA(x,"models")), "\n")
2630
cat("Attribute structure =",extract(x,"att.dist"),"\n")
27-
if (extract.GDINA(x,"ngroup")==1&&extract.GDINA(x,"att.dist")=="higher.order") cat("Higher-order model =",extract(x,"higher.order")$model,"\n")
31+
if (any(extract.GDINA(x,"att.dist")=="higher.order")) cat("Higher-order model =",extract(x,"higher.order")$model,"\n")
2832
tmp <- max(extract.GDINA(x,"Q"))
2933
cat("Attribute level =",ifelse(tmp>1,"Polytomous","Dichotomous"),"\n")
3034
cat("===============================================\n")
@@ -33,8 +37,8 @@ print.GDINA <-
3337
cat("Number of iterations =", max(extract.GDINA(x,"nitr")), "\n")
3438
cat("For the final iteration:\n")
3539
cat(" Max abs change in item success prob. =", formatC(extract(x,"dif.p"), digits = 4, format = "f"), "\n")
36-
cat(" Max abs change in population prop. =", formatC(extract(x,"dif.prior"), digits = 4, format = "f"), "\n")
37-
cat(" Change in deviance =", formatC(extract(x,"dif.LL"), digits = 4, format = "f"), "\n")
40+
cat(" Max abs change in mixing proportions =", formatC(extract(x,"dif.prior"), digits = 4, format = "f"), "\n")
41+
cat(" Change in -2 log-likelihood =", formatC(extract(x,"dif.LL"), digits = 4, format = "f"), "\n")
3842
cat("Time used =", format(extract(x,"time"), digits = 4), "\n")
3943
}
4044
#' @export

R/utils.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ if (!is.null(catprob.parm)){
4343
if (att.str) {
4444
if (max(Q)>1) stop("Attribute structure cannot be specified if attributes are polytomous.",call. = FALSE)
4545
if(any(att.dist=="higher.order")) stop("Higher-order structure is not allowed if att.str = TRUE.",call.=FALSE)
46+
if(any(att.dist=="independent")) stop("Independent structure is not allowed if att.str = TRUE.",call.=FALSE)
47+
if(any(att.dist=="loglinear")) stop("Loglinear structure is not allowed if att.str = TRUE.",call.=FALSE)
4648
if(any(model<0|model>2))stop("Only DINA, DINO and G-DINA is allowed for structured attributes.",call. = FALSE)
4749
}
4850

man/GDINA.Rd

Lines changed: 10 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)