Skip to content

Commit 55fa795

Browse files
committed
version for CRAN
1 parent e123118 commit 55fa795

33 files changed

Lines changed: 730 additions & 83 deletions

DESCRIPTION

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: tmt
22
Type: Package
33
Title: Estimation of the Rasch Model for Multistage Tests
4-
Version: 0.3.6-1
5-
Date: 2025-12-04
4+
Version: 0.3.6-4
5+
Date: 2025-12-05
66
Authors@R: c(
77
person(given = "Jan",
88
family = "Steinfeld",
@@ -27,7 +27,7 @@ License: GPL-3
2727
LazyLoad: yes
2828
VignetteBuilder: knitr
2929
Depends:
30-
R (>= 3.0)
30+
R (>= 4.4.0)
3131
Encoding: UTF-8
3232
NeedsCompilation: yes
3333
Suggests:
@@ -41,7 +41,7 @@ Suggests:
4141
Imports:
4242
parallel,
4343
ggplot2,
44-
Rcpp (>= 0.12.0),
44+
Rcpp (>= 1.0.0),
4545
stats,
4646
rlang
4747
LinkingTo: Rcpp

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# tmt 0.3.6-1
1+
# tmt 0.3.6-4
22
* fixed testthat error
33

44
# tmt 0.3.6-0

R/helper_functions.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,8 @@ thresholds_to_probs <- function(thres, opts = "mstdesign", row = TRUE){
10071007

10081008
if (row) {
10091009
if (nrow(thres)==1) {
1010-
thres_diff <- cbind(thres[1,,drop=FALSE],t(diff(thres)))
1010+
# thres_diff <- cbind(thres[1, , drop = FALSE], t(diff(thres)))
1011+
thres_diff <- thres[1, , drop = FALSE]
10111012
} else {
10121013
thres_diff <- cbind(thres[1,],t(diff(thres)))
10131014
}

R/raschmodel.mst.R

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
66
call <- call_intern
77
}
88
# ----------------------------
9+
# diagnostic
10+
# a0 <- Sys.time(); cat("Start:",format(a0,"%H:%M:%S")); flush.console()
11+
# ----------------------------
912
if(inherits(dat, "list") & "mstdesign" %in% class(dat)){
1013
mstdesign <- dat$mstdesign
1114
dat <- dat$data
@@ -24,13 +27,32 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
2427
if(!is.null(mstdesign)) {
2528
mstdesign_orig <- mstdesign
2629
}
30+
# else {
31+
# mstdesign_orig <- mstdesign
32+
# }
2733

34+
################################################################################################
35+
# todo: MST Design should be added for additional plot
36+
# if (!any(colnames(dat) %in% "branching")) {
37+
# stop("branching design is required in the submitted data, with the column name 'branching'")
38+
# }
39+
40+
# design <- dat[,"branching"]
41+
# dat <- dat[,!colnames(dat) %in% "branching"]
42+
################################################################################################
2843
# preparing the submitted mst design
2944
designelements <- tmt_mstdesign(mstdesign = mstdesign, options = c("design","items"))
3045
items_design <- designelements$items
3146
cumulative <- ifelse(any(class(designelements$design)=="cumulative"),TRUE,FALSE)
3247
mstdesign <- apply(designelements$design,2,as.character)
48+
# startmodules <- designelements$start
49+
# info_startval <- NULL
3350

51+
# if(nrow(startmodules)==1){
52+
# info_startval <- strsplit(startmodules[,"items_to"],",")[[1]]
53+
# }
54+
55+
3456
names_dat <- colnames(dat)
3557

3658
precondition <- NULL
@@ -51,6 +73,9 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
5173
cat("The following items are specified in the mstdesign, but not in the dataset: ")
5274
cat(items_design[!items_design %in% names_dat],"\n")
5375
}
76+
# if (length(status)!=0){
77+
# cat("The following items had to be excluded, due to (nearly) full '1' or '0' responses: ",status,"\n")
78+
# }
5479
stop("It is necessary, that all Items in the dataset are also specified in the submitted mstdesign and vice versa! \nPlease update the design and the data.\n")
5580
}
5681

@@ -106,6 +131,10 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
106131
cs <- colSums(dat[,names_dat] * weights, na.rm = TRUE)
107132
ws <- colSums(!is.na(dat[,names_dat]) * weights)
108133
start <- log(ws - cs) - log(cs)
134+
# choose for start module informative starting values
135+
# if(!is.null(info_startval)){
136+
# start[!names(start)%in%info_startval] <- 0
137+
# }
109138
}
110139
start <- start[-i]
111140
desmat <- rbind(diag(1,nrow = length(start) ), -1)
@@ -116,6 +145,10 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
116145
cs <- colSums(dat[,names_dat] * weights, na.rm = TRUE)
117146
ws <- colSums(!is.na(dat[,names_dat]) * weights)
118147
start <- log(ws - cs) - log(cs)
148+
# choose for start module informative starting values
149+
# if(!is.null(info_startval)){
150+
# start[!names(start)%in%info_startval] <- 0
151+
# }
119152
}
120153
start <- start[-1]
121154
desmat <- rbind(0,diag(1,nrow=length(start)))
@@ -127,7 +160,7 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
127160
esf <- esf_mst_sum_vector(parlist = par_i, ojlist = oj_i, probs = probabilities_i, order = 0,
128161
minSolved = minSolved_i, maxSolved = maxSolved_i,
129162
minSolved_design = minSolved_stage_i, maxSolved_design = maxSolved_stage_i, cumulative = cumulative_i)[[1]]
130-
163+
#esf[(sum(minSolved_i) + 1):(sum(maxSolved_i) + 1)] <- log(esf[(sum(minSolved_i)+1):(sum(maxSolved_i)+1)])
131164
esf[(tail(minSolved_stage_i,n=1) + 1):(tail(maxSolved_stage_i,n=1) + 1)] <- log(esf[(tail(minSolved_stage_i,n=1) + 1):(tail(maxSolved_stage_i,n=1) + 1)])
132165
return( -sum( cs_i * unlist(par_i) ) - sum(rf_i * esf) )
133166
}
@@ -181,8 +214,9 @@ raschmodel.mst <- function(dat, mstdesign = NULL, weights = NULL, start = NULL,
181214
out <- colSums(out[, drop = FALSE]) %*% desmat
182215
return(out)
183216
}
184-
185-
# analytival hessian matrix
217+
# esf[(sum(minSolved_i) + 1):(sum(maxSolved_i) + 1)] <- log(esf[(sum(minSolved_i)+1):(sum(maxSolved_i)+1)])
218+
219+
# # analytival hessian matrix
186220
ahessian <- function(par) {
187221
par_n <- c(desmat %*% par)
188222
par_i <- lapply(items_l, FUN = function(x){

R/sim.rm.R

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sim.rm <- function(theta, b, seed = NULL){
88
if (((length(theta) + length(b) )== 2) && !is.null(seed) && length(seed) != 2) {
99

1010
warning("It is necessary to set a seed for both theta and beta if no vector is passed. The specified seed was used for the theta parameters, the following is used for beta: ", seed + 1)
11-
11+
#> Warning: This is what a warning looks like
1212
seed_theta <- seed
1313
seed_beta <- seed + 1
1414
}
@@ -29,6 +29,8 @@ sim.rm <- function(theta, b, seed = NULL){
2929
seed_beta <- seed
3030
}
3131

32+
# cat("seed sim: ",seed)
33+
3234
if(length(theta) == 1) {
3335
if(!is.null(seed_theta)) {
3436
set.seed(seed_theta)
@@ -42,6 +44,13 @@ sim.rm <- function(theta, b, seed = NULL){
4244
}
4345
b <- stats::rnorm(b, mean = 0, sd = 1)
4446
}
47+
# if(!is.null(seed)){
48+
# set.seed(seed)
49+
# resp <- outer(theta, b, "-")
50+
# p_exp <- exp(resp)
51+
# prop_solve <- p_exp/(1 + p_exp)
52+
# dat.resp <-(prop_solve > matrix(stats::runif(length(b)*length(theta)),length(theta),length(b)))*1
53+
# } else {
4554
resp <- outer(theta, b, "-")
4655
p_exp <- exp(resp)
4756
prop_solve <- p_exp/(1 + p_exp)

R/tmt_gmc.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ tmt_gmc <- function (object,
4444
if (is.null(yaxis)) {
4545
yaxis <- paste("item parameter for group: ", names(object$betapars_subgroup)[2], sep = "")
4646
}
47+
#if (!is.null(drop) & !all(drop%in%colnames(object$fitob[[1]]$data))) {
48+
# stop("Only names in the vector 'drop' are permitted which are also in the data.")
49+
#}
4750
if(!is.null(info)) info <- info[!names(info)%in%drop]
51+
#if (!is.null(info) & !all(names(info) %in% colnames(object$data))) {
52+
# stop("Only names in the vector 'drop' are permitted which are also in the data.")
53+
#}
4854
# ------------------------------------------------------
4955
subgroup_1 <- object$betapars_subgroup[[1]]
5056
subgroup_2 <- object$betapars_subgroup[[2]]

R/tmt_mstdesign.R

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,64 @@ tmt_mstdesign <- function(mstdesign, options = c("design", "simulation", "module
3232
# some possible misspecification
3333
checinput <- strsplit(mstdesign,"\n")[[1]]
3434
checkinput <- gsub("\\s","",checinput)
35+
# misspecified <- c("\\=[^:]|\\=[^~~]|[^~~=]|~=|~~|~|<~|\\*")
3536
# 2020-03-27 updated list
3637
misspecified <- "=:|=~~|~~=|~=|~~|<~|\\*|"
37-
38+
# miss_list <- list()
39+
40+
# checkinput[gregexpr("=:",checkinput, perl = TRUE)>0]
41+
# checkinput[gregexpr("=~~",checkinput, perl = TRUE)>0]
42+
# checkinput[gregexpr("~~=",checkinput, perl = TRUE)>0]
43+
# checkinput[gregexpr("~=",checkinput, perl = TRUE)>0]
44+
# checkinput[gregexpr("~~",checkinput, perl = TRUE)>0]
45+
# checkinput[gregexpr("~",checkinput, perl = TRUE)>0]
46+
# checkinput[gregexpr("<~",checkinput, perl = TRUE)>0]
47+
# checkinput[gregexpr("\\*",checkinput, perl = TRUE)>0]
48+
49+
# ein paar Beispiele ausprobieren
50+
# checkinput[length(checkinput)+1] <- "das=:istErsterTest"
51+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
52+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
53+
# checkinput[length(checkinput)+1] <- "das=~~istZweiterTest"
54+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
55+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
56+
# checkinput[length(checkinput)+1] <- "das~~=istDritterTest"
57+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
58+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
59+
# checkinput[length(checkinput)+1] <- "das~=istVierterTest"
60+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
61+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
62+
# checkinput[length(checkinput)+1] <- "das~~istFuenfterTest"
63+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
64+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
65+
# checkinput[length(checkinput)+1] <- "das~istSechsterTest"
66+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
67+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
68+
# checkinput[length(checkinput)+1] <- "das<~istSiebterTest"
69+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
70+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
71+
# checkinput[length(checkinput)+1] <- "das*istAchterTest"
72+
# checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
73+
# checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
74+
3875
checlocation <- gregexpr(misspecified,checkinput, perl = TRUE)
3976
result_misspecified <- checkinput[unlist(lapply(checlocation,function(x) any(attr(x,"match.length")>0)))]
4077

78+
# gregexpr("\\+[^~]",checkinput)
79+
# "~|\\+[^=]|\\+\\="
80+
81+
# 2020-03-27 fixed loop
82+
# for(m in 1:length(misspecified)){
83+
# miss_list[[m]] <- grep(misspecified[m], checkinput, value = TRUE, perl = TRUE)
84+
# }
85+
4186
if (length(result_misspecified)>0) {
4287
stop("The submitted mstdesign is misspecified, please correct the following expression/s:\n",
4388
paste0(" - ",result_misspecified,collapse="\n")
4489
)
4590
}
4691

47-
# ...................................................................................................
92+
# ...................................................................................................
4893

4994
# clean mstdesign input:
5095
tmt.syntax <- mstdesign
@@ -65,11 +110,22 @@ tmt_mstdesign <- function(mstdesign, options = c("design", "simulation", "module
65110
# create list for the simulation function
66111
# -----------------------------------
67112
# number of modules & branches
68-
113+
114+
# für tmtd muss schon überprüft werden, ob es preconditions gibt...dann muss die Simulationsfunktion angepasst werden und die Info in das Design übernommen werden
115+
# die Paths am besten reduzieren um die Einträge, dann gehen die übrigen Funktionen noch...Evtl. die Info in einer anderen Funktion aufbereiten und dann je nach Bedarf den output hinzufügen. Letztlich muss man allerdings darauf achten, dass die Anzahl der Zeilen dann bspw. im design-output um die preconditions ergänzt wird!!
116+
117+
# preconditions können mit ~ enden, aber auch mit +=...wie differenzieren? Müssen eingangs oben definiert werden?
118+
119+
120+
69121
n.modules <- length(grep("=~",tmtd, fixed = TRUE))
122+
# n.start <- length(grep("==",tmtd, fixed = TRUE))
70123
n.branches <- length(grep(":=",tmtd, fixed = TRUE))
124+
125+
# l.stages <- nchar(as.character(tmtd[grepl(":=",tmtd, fixed = TRUE)])) -
126+
# nchar( gsub("\\+", "", tmtd[grepl(":=",tmtd, perl = TRUE)]))
127+
# n.stages <- max(l.stages)
71128
n.preconditions <- length(grep("==",tmtd)) # grep only '~'
72-
73129
if (n.preconditions != 0) {
74130
c.preconditions <- grep("==",tmtd, value = TRUE)
75131
c.preconditions <- strsplit(c.preconditions,"==")
@@ -83,6 +139,7 @@ tmt_mstdesign <- function(mstdesign, options = c("design", "simulation", "module
83139
# ---------------------------
84140
preconditions_sim <- preconditions <- start <- simulation <- design <- items <- NULL
85141

142+
86143
modules <- hfun.modules(tmtd = tmtd,
87144
n.branches = n.branches,
88145
n.modules = n.modules)
@@ -93,6 +150,7 @@ tmt_mstdesign <- function(mstdesign, options = c("design", "simulation", "module
93150

94151
if (any(av.preconditions$value%in%modules[,"from"])) stop("The operator '==' is now used for the definition of preconditions!\n * Please integrate the start module into the mst design and \n * start the function again.")
95152

153+
# nur bei der kumulativen verzweigung muss das Design entsprechend angepasst werden
96154
routing_type <- hfun.preconditionoperator(tmtd = tmtd,
97155
preconditions = av.preconditions)
98156

@@ -105,11 +163,60 @@ tmt_mstdesign <- function(mstdesign, options = c("design", "simulation", "module
105163
tmtd <- preconditions$tmtd
106164
n.branches <- nrow(preconditions$paths)
107165
preconditions_sim <- preconditions$precondition_matrix
166+
# n.stages <- length(grep("module",colnames(preconditions$paths)))
108167
}
109168

110169
}
111170

112171

172+
173+
174+
175+
176+
# 2020-05-21 added for probabilistic-cumulative designs
177+
# branches <- tmtd[grepl(":=", tmtd, fixed = TRUE)]
178+
# if (any(grepl("+=",branches)) {
179+
180+
181+
# branches <- strsplit_storing(branches,":=")
182+
# colnames(branches) <- c("path","operator_0", "path_original")
183+
# branches <- strsplit_storing(variable = branches,
184+
# split = c("~","+=","+"),
185+
# cols = "path_original",
186+
# new_names = c("module","operator"))
187+
188+
# i <- 1
189+
# for (m in grep("module",colnames(branches),value=TRUE)){
190+
# branches <- strsplit_storing(branches,"\\(|\\)",m, fixed = FALSE, new_names = paste0(c("module_","rule_"),i), store_operator = FALSE)
191+
# i <- i + 1
192+
# }
193+
# # nun die rules durch die lenght der items ersetzen und dann jeweils um eines reduzieren
194+
# items <- unlist(regmatches(modules[,"items"], gregexpr( "(?<=\\().+?(?=\\))", modules[,"items"], perl = TRUE)))
195+
# possible_scores <- sapply(items,function(x) paste0("0:",length(strsplit(x,",")[[1]])) , simplify=TRUE,USE.NAMES=FALSE)
196+
# modules_score <- cbind(modules[,"from"],possible_scores)
197+
# colnames(modules_score) <- c("module","score")
198+
199+
200+
# for (o in seq(grep("rule",colnames(branches)))) {
201+
# pos_module <- match(c(branches[,paste0("module_",o)]), modules_score[,"module"])
202+
# branches[,paste0("rule_",o)] <- modules_score[,"score"][pos_module]
203+
# }
204+
205+
# # nur für die mittleren Fälle
206+
# cases <- grep("rule",colnames(branches), value = TRUE)
207+
# cases <- cases[-length(cases)]
208+
209+
# branches_expand <- expand.matrix(variable = branches,
210+
# names = cases)
211+
# branches_expand <- branches_expand[,seq(grep(cases,colnames(branches_expand))+2)]
212+
213+
214+
# operator_check <- rowSums(apply(branches_expand[,grep(cases, colnames(branches_expand))+1,drop=FALSE],2,function(x) x%in%"+="))
215+
# branches_expand <- branches_expand[operator_check==length(cases),]
216+
217+
# }
218+
219+
113220
if ("simulation" %in% options) simulation <- hfun.simulation(modules = modules,
114221
tmtd = tmtd_sim,
115222
preconditions = preconditions_sim)

0 commit comments

Comments
 (0)