This report summarises all previous results computed with the mirt package v.1.28.4. I´m using what I´m calling as Artificial imputation (i.e., data with no missing cases because all values were imputed with 0 or 2), and what I´m calling as NA Data (data with missing cases allowed). I have exported all data to flexmirt and I carried out the same analyses using this software as well. Just to notice, flexmirt uses -9 to identify its missing cases and I have changed “NA values” with the flexmirt default. An excel file has been sent in the e-mail that you received with the link for this report and this file gathers all flexmirt and mirt results.
All computational codes used is printed in this html file. Once I’m working on this dataset for a very long time, I´m afraid that small errors or inconsistencies could not be filtered during the proccess. Therefore, I’ll be grateful if everyone look at the following codes (all logic is very straightforward) aiming at identifying any errors.
Thank you
overall_mirt_results <- data.frame(m2_gm_artificial) %>%
bind_rows(.,m2_fm_artificial) %>%
bind_rows(.,m2_cg_artificial) %>%
bind_rows(.,m2_cm_artificial) %>%
bind_rows(.,m2_ps_artificial) %>%
mutate(model = row_number()) %>%
mutate(model = case_when(
model == "1" ~ "Gross motor",
model == "2" ~ "Fine motor",
model == "3" ~ "Problem solving",
model == "4" ~ "Communication",
model == "5" ~ "Personal and social"
)) %>%
select(model, everything())
overall_mirt_results %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| model | M2 | df | p | RMSEA | RMSEA_5 | RMSEA_95 | SRMSR | TLI | CFI |
|---|---|---|---|---|---|---|---|---|---|
| Gross motor | 19367.047 | 1127 | 0 | 0.107 | 0.106 | 0.108 | 0.093 | 0.939 | 0.941 |
| Fine motor | 7653096.711 | 1224 | 0 | 2.659 | 2.653 | 2.658 | 0.096 | -52.385 | 0.000 |
| Problem solving | 1777.595 | 1224 | 0 | 0.024 | 0.022 | 0.027 | 0.139 | 0.996 | 0.996 |
| Communication | 2706.134 | 1175 | 0 | 0.039 | 0.037 | 0.041 | 0.092 | 0.990 | 0.991 |
| Personal and social | 2952.016 | 1175 | 0 | 0.034 | 0.032 | 0.035 | 0.125 | 0.991 | 0.991 |
(#fig:flexmirt - artificial dataset)Flexmirt results
(#fig:flexmirt - na dataset)Flexmirt results 2
The following chunk gets the SPSS dataset, locate the floor and the ceiling and replace all previously imputed values by NA. The function that performs theses action is named as altMask. In addition, you can check all the steps by reading the comments close to each function.
#gm_original <- asqi_gm_online
#Slice the data
gm_items_na <- gm_original %>%
select(gm_floor:gm_20_p) #get all ASQ-I items
#change names
gm_items_na <- gm_items_na %>%
rename_at(vars(-gm_floor, -gm_ceiling),
function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to understand
#change str for numeric
gm_items_na <- gm_items_na %>%
mutate_at(vars(gm_floor, gm_ceiling),
list(~as.numeric(.))) #now, all variables are numeric
#replace na with the first/last option possible
#if the floor or the ceiling were missing, I'll fix it.
gm_items_na <- gm_items_na %>%
mutate_at(vars(gm_floor), list(~if_else(is.na(.),1,.)))
gm_items_na <- gm_items_na %>%
mutate_at(vars(gm_ceiling), list(~if_else(is.na(.),69,.)))
#Now I'll run the function I've created
gm_items_na %>%
mutate(rowIdx = 1:n()) %>%
gather(col, value, starts_with("y")) %>%
mutate(value = altMask(parse_number(col), value, gm_floor, gm_ceiling)) %>%
spread(col, value) %>%
arrange(rowIdx) %>%
select(-rowIdx) -> gm_items_na
#Order
gm_items_na <- gm_items_na %>% select(gm_floor, gm_ceiling, paste("y", seq(1, ncol(select(., starts_with("y"))), 1), sep=""), everything())
#supress floor and ceiling
gm_items_na <- gm_items_na %>% select(-gm_floor, -gm_ceiling)
The plot below shows the missing quantity in this domain:
I’ll run the IRT model.
#run the model
set.seed(123) #replicable results
mod_gm_na <- mirt(gm_items_na, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_gm_na <- M2(mod_gm_na, type="C2", calcNull = FALSE, na.rm=TRUE)
The M2 statistics was not computed: NaN, 2277, NaN, NaN, 0, 0, NaN, but the model coefficients were. These results are reported in the table below:
coef(mod_gm_na, IRTpars=TRUE, simplify = TRUE) %>%
data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| y1 | 0.163 | -24.843 | -15.040 |
| y2 | 0.650 | -7.883 | -5.310 |
| y3 | 1.555 | -3.887 | -2.444 |
| y4 | 0.613 | -9.552 | -4.373 |
| y5 | 0.812 | -5.518 | -2.988 |
| y6 | 0.971 | -4.905 | -2.481 |
| y7 | 1.877 | -3.525 | -1.996 |
| y8 | 3.364 | -2.428 | -1.590 |
| y9 | 3.569 | -1.738 | -1.147 |
| y10 | 1.868 | -2.771 | -1.886 |
| y11 | 1.965 | -2.186 | -1.494 |
| y12 | 2.098 | -1.070 | -0.715 |
| y13 | 2.211 | -1.269 | -0.638 |
| y14 | 3.053 | -1.158 | -0.730 |
| y15 | 1.324 | -1.742 | -0.931 |
| y16 | 2.544 | -0.855 | -0.622 |
| y17 | 1.673 | -0.300 | -0.001 |
| y18 | 1.806 | -0.266 | 0.162 |
| y19 | 0.276 | 0.540 | 2.178 |
| y20 | -0.188 | 3.010 | 0.495 |
| y21 | -0.474 | 3.170 | 1.571 |
| y22 | -1.365 | 0.853 | 0.275 |
| y23 | -1.761 | 0.702 | 0.167 |
| y24 | -2.177 | 0.272 | -0.082 |
| y25 | -0.893 | 1.316 | 0.520 |
| y26 | -2.845 | -0.054 | -0.190 |
| y27 | -2.527 | 0.181 | -0.045 |
| y28 | -1.789 | 0.115 | -0.304 |
| y29 | -0.600 | 0.197 | -0.673 |
| y30 | -0.294 | 2.600 | 0.224 |
| y31 | 0.860 | -3.061 | -2.283 |
| y32 | 0.987 | -2.512 | -1.575 |
| y33 | 1.457 | -1.820 | -1.363 |
| y34 | 1.190 | -2.010 | -1.220 |
| y35 | 2.157 | -1.042 | -0.629 |
| y36 | 2.365 | -1.374 | -0.903 |
| y37 | 1.973 | -0.999 | -0.320 |
| y38 | 4.111 | -0.695 | -0.388 |
| y39 | 1.656 | -1.294 | -0.616 |
| y40 | 3.040 | -0.690 | -0.314 |
| y41 | 5.720 | -0.393 | -0.196 |
| y42 | 1.769 | -0.723 | 0.193 |
| y43 | 5.925 | -0.149 | 0.115 |
| y44 | 1.948 | -0.832 | -0.325 |
| y45 | 2.775 | -0.146 | 0.387 |
| y46 | 3.802 | 0.037 | 0.368 |
| y47 | 4.013 | 0.259 | 0.507 |
| y48 | 2.498 | 0.549 | 0.967 |
| y49 | 3.570 | 0.608 | 1.060 |
| y50 | 1.881 | -1.306 | -0.229 |
| y51 | 1.901 | -0.430 | 0.119 |
| y52 | 2.390 | 0.628 | 1.199 |
| y53 | 4.811 | 0.321 | 0.701 |
| y54 | 1.776 | -0.138 | 0.362 |
| y55 | 1.074 | -1.514 | -0.990 |
| y56 | 1.889 | 0.135 | 0.855 |
| y57 | 1.408 | -1.511 | NA |
| y58 | 1.342 | -1.616 | -0.245 |
| y59 | 1.685 | -0.369 | 0.815 |
| y60 | 2.712 | -0.658 | NA |
| y61 | 2.474 | 0.041 | 0.643 |
| y62 | 3.749 | -0.074 | 0.458 |
| y63 | 2.266 | -0.573 | 0.037 |
| y64 | 1.441 | -2.395 | -1.196 |
| y65 | 1.579 | -0.785 | -0.020 |
| y66 | 1.164 | 0.148 | 1.343 |
| y67 | 1.966 | 1.711 | 2.172 |
| y68 | 1.379 | 1.651 | 1.950 |
| y69 | 1.181 | -0.472 | 1.064 |
#replace NA by -99
gm_items_na <- gm_items_na %>%
mutate_all(., funs(replace_na(., -9)))
write.table(gm_items_na, file = "gm_items_na.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
Now I’ll test the dataset with the artificial imputation (2s and 0s). Note this dataset has no missing data.
gm_items_c_artificial <- gm_original %>%
select(gm_floor:gm_20_p)#get all ASQ-I items
#complete dataset
items_up60 <- c(
"gm_1_2",
"gm_4_2",
"gm_3_2",
"gm_5_2",
"gm_6_2",
"gm_2_2",
"gm_3_4",
"gm_4_4",
"gm_5_4",
"gm_6_4",
"gm_1_6",
"gm_2_6",
"gm_3_6",
"gm_4_6",
"gm_5_6",
"gm_6_6",
"gm_5_8",
"gm_6_8",
"gm_4_10",
"gm_5_10",
"gm_6_10",
"gm_4_12",
"gm_5_12",
"gm_6_12",
"gm_4_14",
"gm_5_14",
"gm_6_14",
"gm_5_16",
"gm_6_16",
"gm_5_18",
"gm_6_18",
"gm_5_20",
"gm_6_20",
"gm_5_22",
"gm_6_22",
"gm_5_27",
"gm_6_27",
"gm_6_30",
"gm_6_33",
"gm_6_36",
"gm_5_42",
"gm_6_42",
"gm_3_48",
"gm_4_48",
"gm_5_48",
"gm_6_48",
"gm_6_54",
"gm_5_60",
"gm_6_60",
"gm_1_p",
"gm_2_p",
"gm_3_p",
"gm_4_p",
"gm_5_p",
"gm_6_p",
"gm_7_p",
"gm_8_p",
"gm_9_p",
"gm_10_p",
"gm_11_p",
"gm_12_p",
"gm_13_p",
"gm_14_p",
"gm_15_p",
"gm_16_p",
"gm_17_p",
"gm_18_p",
"gm_19_p",
"gm_20_p")
#create ds
gm_items_c_artificial <- gm_items_c_artificial %>%
select(items_up60)
#check for missing
plot_missing(gm_items_c_artificial)
#remove missing
gm_items_c_artificial <- gm_items_c_artificial %>%
dplyr::select(-c(ends_with("_p")))
#check
plot_missing(gm_items_c_artificial)
#change names
gm_items_c_artificial <- gm_items_c_artificial %>%
rename_all(.,
function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to understand
# to flexmirt
write.table(gm_items_c_artificial, file = "gm_items_c_artificial.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
#run the model
set.seed(123)
mod_gm_artificial <- mirt(gm_items_c_artificial, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_gm_artificial <- M2(mod_gm_artificial, type="C2")
The M2 statistics revealed an excelent fit. See below:
1.936704710^{4}, 1127, 0, 0.1070237, 0.1056656, 0.1083115, 0.0930104, 0.9385562, 0.9411164.
The coefficients are reported in the next table.
coef(mod_gm_artificial, IRTpars=TRUE, simplify = TRUE) %>%
data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| y1 | 2.385 | -4.268 | -3.492 |
| y2 | 2.503 | -4.195 | -3.455 |
| y3 | 4.320 | -3.150 | -2.574 |
| y4 | 2.733 | -4.387 | -3.028 |
| y5 | 3.227 | -3.378 | -2.662 |
| y6 | 3.302 | -3.269 | -2.478 |
| y7 | 6.812 | -2.559 | -2.132 |
| y8 | 8.130 | -2.184 | -1.895 |
| y9 | 4.604 | -3.018 | -2.331 |
| y10 | 4.604 | -2.614 | -2.229 |
| y11 | 4.690 | -2.365 | -2.054 |
| y12 | 5.336 | -1.899 | -1.608 |
| y13 | 5.364 | -1.831 | -1.677 |
| y14 | 7.151 | -1.854 | -1.645 |
| y15 | 3.671 | -1.981 | -1.693 |
| y16 | 6.671 | -1.321 | -1.188 |
| y17 | 7.200 | -1.629 | -1.523 |
| y18 | 9.138 | -1.304 | -1.110 |
| y19 | 7.636 | -0.896 | -0.706 |
| y20 | 6.504 | -0.943 | -0.707 |
| y21 | 7.703 | -0.661 | -0.443 |
| y22 | 5.130 | -1.070 | -0.797 |
| y23 | 7.258 | -0.592 | -0.373 |
| y24 | 13.170 | -0.183 | -0.111 |
| y25 | 4.173 | -0.504 | -0.302 |
| y26 | 7.014 | -0.354 | -0.187 |
| y27 | 8.140 | -0.193 | -0.063 |
| y28 | 7.586 | -0.082 | 0.144 |
| y29 | 5.240 | 0.046 | 0.218 |
| y30 | 6.006 | 0.167 | 0.365 |
| y31 | 5.292 | 0.158 | 0.414 |
| y32 | 5.834 | 0.147 | 0.431 |
| y33 | 6.297 | 0.276 | 0.444 |
| y34 | 6.419 | 0.771 | 0.950 |
| y35 | 5.623 | 0.423 | 0.661 |
| y36 | 8.709 | 0.953 | 1.065 |
| y37 | 4.081 | 0.639 | 0.979 |
| y38 | 5.990 | 0.797 | 0.995 |
| y39 | 3.864 | 0.287 | 0.568 |
| y40 | 10.002 | 1.093 | 1.247 |
| y41 | 4.149 | 0.861 | 1.260 |
| y42 | 5.004 | 0.566 | 0.786 |
| y43 | 4.185 | 0.593 | 0.867 |
| y44 | 6.848 | 1.219 | 1.402 |
| y45 | 6.926 | 1.350 | 1.495 |
| y46 | 5.754 | 1.128 | 1.399 |
| y47 | 4.864 | 0.837 | 1.037 |
| y48 | 5.966 | 1.578 | 1.858 |
| y49 | 4.205 | 1.562 | 1.807 |
mirt package did not compute a valid model when missing data were present. Its coefficient results should be seen carefully.
mirt package could compute a model when the dataset had artificial imputation (2s and 0s). Its results allow conclude that this model is well-adjusted.
The following code repeats the process described in the beginning.
#Slice the data
fm_items_na <- fm_original %>%
select(fm_floor:fm_3_p) #get all ASQ-I items
#change names
fm_items_na <- fm_items_na %>%
rename_at(vars(-fm_floor, -fm_ceiling),
function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to understand
#change str for numeric
fm_items_na <- fm_items_na %>%
mutate_at(vars(fm_floor, fm_ceiling),
list(~as.numeric(.))) #now, all variables are numeric
#replace na with the first/last option possible
#if the floor or the ceiling were missing, I'll fix it.
fm_items_na <- fm_items_na %>%
mutate_at(vars(fm_floor), list(~if_else(is.na(.),1,.)))
fm_items_na <- fm_items_na %>%
mutate_at(vars(fm_ceiling), list(~if_else(is.na(.),64,.)))
#Now I'll run the function I've created
fm_items_na %>%
mutate(rowIdx = 1:n()) %>%
gather(col, value, starts_with("y")) %>%
mutate(value = altMask(parse_number(col), value, fm_floor, fm_ceiling)) %>%
spread(col, value) %>%
arrange(rowIdx) %>%
select(-rowIdx) -> fm_items_na
#Order
fm_items_na <- fm_items_na %>% select(fm_floor, fm_ceiling, paste("y", seq(1, ncol(select(., starts_with("y"))), 1), sep=""), everything())
#supress floor and ceiling
fm_items_na <- fm_items_na %>% select(-fm_floor, -fm_ceiling)
The plot below shows the missing quantity in this domain:
I’ll run the IRT model.
#run the model
set.seed(123)
mod_fm_na <- mirt(fm_items_na, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_fm_na <- M2(mod_fm_na, type="C2", na.rm=TRUE)
Unfortunately, even after 2000 iterations, the convergence was not reached. Similar to what I carried out before, I’ve computed the summary and the model coefficients. These results are presented in the next Table.
coef(mod_fm_na, IRTpars=TRUE, simplify = TRUE) %>% data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| y1 | 2.149 | -3.537 | -2.918 |
| y2 | 1.636 | -4.429 | -3.477 |
| y3 | 1.128 | -4.536 | -2.880 |
| y4 | 1.790 | -3.915 | -2.885 |
| y5 | 2.449 | -2.971 | -2.490 |
| y6 | 5.244 | -2.932 | -2.487 |
| y7 | 20082757.239 | -1.544 | NA |
| y8 | 3.937 | -2.543 | -2.323 |
| y9 | 7.153 | -2.326 | -2.038 |
| y10 | 7.670 | -2.180 | -1.981 |
| y11 | 6.789 | -2.186 | -1.997 |
| y12 | 6.884 | -1.963 | -1.792 |
| y13 | 3.197 | -2.518 | -2.040 |
| y14 | 5.817 | -1.989 | -1.768 |
| y15 | 11.353 | -1.668 | -1.568 |
| y16 | 10.736 | -1.686 | -1.554 |
| y17 | 14.039 | -1.610 | -1.446 |
| y18 | 7.387 | -1.583 | -1.434 |
| y19 | 4.564 | -1.707 | -1.370 |
| y20 | 5.919 | -1.560 | -1.333 |
| y21 | 5.226 | -1.628 | -1.278 |
| y22 | 6.402 | -1.407 | -1.229 |
| y23 | 3.800 | -1.720 | -1.377 |
| y24 | 4.515 | -1.402 | -1.149 |
| y25 | 4.628 | -0.932 | -0.741 |
| y26 | 4.608 | -0.997 | -0.662 |
| y27 | 3.216 | -1.127 | -0.821 |
| y28 | 2.717 | -1.022 | -0.622 |
| y29 | 4.050 | -0.723 | -0.395 |
| y30 | 2.815 | -1.189 | -0.366 |
| y31 | 3.498 | -0.367 | 0.028 |
| y32 | 2.275 | -1.170 | -0.645 |
| y33 | 1.940 | -1.528 | -0.361 |
| y34 | 5.530 | 0.194 | 0.438 |
| y35 | 6.056 | 0.118 | 0.433 |
| y36 | 4.637 | 0.062 | 0.434 |
| y37 | 2.693 | -0.006 | 0.541 |
| y38 | 2.372 | 0.307 | 0.656 |
| y39 | 0.916 | -1.063 | 0.697 |
| y40 | 1.923 | 0.368 | 0.907 |
| y41 | 1.462 | 0.219 | 1.052 |
| y42 | 3.324 | 0.650 | 1.241 |
| y43 | 3.295 | 0.783 | 0.942 |
| y44 | 1.436 | -0.270 | 0.615 |
| y45 | 3.037 | 0.456 | 0.950 |
| y46 | 1.745 | -0.021 | 1.072 |
| y47 | 1.745 | 0.082 | 0.870 |
| y48 | 0.572 | -2.659 | 0.313 |
| y49 | 2.385 | 0.134 | 1.273 |
| y50 | 2.098 | 0.092 | 0.818 |
| y51 | 1.967 | 0.140 | 1.115 |
| y52 | 1.505 | -0.004 | 1.166 |
| y53 | 2.660 | 0.499 | 1.165 |
| y54 | 2.337 | 0.293 | 1.150 |
| y55 | 1.602 | -0.741 | 1.106 |
| y56 | 1.721 | -0.023 | 1.055 |
| y57 | 1.636 | 0.173 | 1.129 |
| y58 | 1.577 | 0.467 | 1.286 |
| y59 | 0.807 | 0.113 | 1.371 |
| y60 | 1.572 | 0.159 | 1.267 |
| y61 | 2.060 | 0.780 | 1.613 |
| y62 | 1.359 | 0.893 | 1.596 |
| y63 | 0.842 | 0.728 | 1.899 |
| y64 | 1.364 | 2.282 | 2.842 |
Please, have a look at “y7” (fm_2_4). In the dataset, 99.66% of values are NA. I don’t know what happened in this case.
#replace NA by -99
fm_items_na <- fm_items_na %>%
mutate_all(., funs(replace_na(., -9)))
write.table(fm_items_na, file = "fm_items_na.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
Now I’ll test the dataset with the artificial imputation (2s and 0s). Note this dataset has no missing data.
#get entire data
fm_items_c_artificial <- fm_original %>%
select(fm_floor:fm_3_p) #get all ASQ-I items
#overall instrument
items_up60 <- c("fm_4_2",
"fm_2_2",
"fm_5_2",
"fm_1_2",
"fm_6_2",
"fm_3_2",
"fm_2_4",
"fm_5_4",
"fm_4_4",
"fm_6_4",
"fm_1_6",
"fm_2_6",
"fm_3_6",
"fm_4_6",
"fm_5_6",
"fm_6_6",
"fm_5_8",
"fm_6_8",
"fm_4_10",
"fm_5_10",
"fm_6_10",
"fm_4_12",
"fm_5_12",
"fm_6_12",
"fm_4_14",
"fm_5_14",
"fm_6_14",
"fm_6_16",
"fm_6_18",
"fm_5_20",
"fm_6_20",
"fm_5_22",
"fm_6_22",
"fm_3_27",
"fm_6_27",
"fm_5_30",
"fm_6_30",
"fm_6_33",
"fm_6_36",
"fm_5_42",
"fm_6_42",
"fm_2_48",
"fm_3_48",
"fm_4_48",
"fm_5_48",
"fm_6_48",
"fm_4_54",
"fm_5_54",
"fm_6_54",
"fm_4_60",
"fm_6_60",
"fm_5_60",
"fm_1_p",
"fm_2_p",
"fm_3_p",
"fm_4_p",
"fm_5_p",
"fm_6_p",
"fm_7_p",
"fm_8_p",
"fm_9_p",
"fm_10_p",
"fm_11_p",
"fm_12_p")
#select specific items
fm_items_c_artificial <- fm_items_c_artificial %>%
dplyr::select(items_up60)
#check for missing
plot_missing(fm_items_c_artificial)
#remove missing
fm_items_c_artificial <- fm_items_c_artificial %>%
dplyr::select(-fm_2_4,-c(ends_with("_p")))
#check
plot_missing(fm_items_c_artificial)
#change names
fm_items_c_artificial <- fm_items_c_artificial %>%
rename_all(.,
function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to
# to flexmirt
write.table(fm_items_c_artificial, file = "fm_items_c_artificial.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
#run the model
set.seed(123)
mod_fm_artificial <- mirt(fm_items_c_artificial, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_fm_artificial <- M2(mod_fm_artificial, type="C2")
The M2 statistics revealed an excelent fit. See below:
7.653096710^{6}, 1224, 0, 2.6592981, 2.6529954, 2.6582551, 0.0956688, -52.384929, 0.
The coefficients are reported in the next table.
coef(mod_fm_artificial, IRTpars=TRUE, simplify = TRUE) %>%
data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| fm_4_2 | 3.029 | -3.362 | -2.907 |
| fm_2_2 | 2.293 | -4.059 | -3.368 |
| fm_5_2 | 2.554 | -3.575 | -2.808 |
| fm_1_2 | 2.442 | -3.597 | -2.820 |
| fm_6_2 | 2.846 | -2.941 | -2.513 |
| fm_3_2 | 4.016 | -3.064 | -2.558 |
| fm_5_4 | 3.522 | -2.595 | -2.352 |
| fm_4_4 | 6.046 | -2.355 | -2.016 |
| fm_6_4 | 5.506 | -2.169 | -1.945 |
| fm_1_6 | 6.357 | -2.167 | -1.929 |
| fm_2_6 | 3.899 | -2.142 | -1.811 |
| fm_3_6 | 6.821 | -1.493 | -1.341 |
| fm_4_6 | 4.810 | -1.872 | -1.610 |
| fm_5_6 | 6.253 | -1.502 | -1.310 |
| fm_6_6 | 5.712 | -1.897 | -1.670 |
| fm_5_8 | 7.800 | -1.384 | -1.147 |
| fm_6_8 | 5.728 | -1.322 | -1.123 |
| fm_4_10 | 4.495 | -1.315 | -0.981 |
| fm_5_10 | 4.853 | -1.200 | -0.951 |
| fm_6_10 | 4.822 | -1.228 | -0.869 |
| fm_4_12 | 4.986 | -1.030 | -0.821 |
| fm_5_12 | 3.270 | -0.391 | -0.059 |
| fm_6_12 | 4.410 | -1.165 | -0.884 |
| fm_4_14 | 4.632 | -0.482 | -0.137 |
| fm_5_14 | 4.440 | -0.439 | -0.233 |
| fm_6_14 | 4.155 | -0.169 | 0.145 |
| fm_6_16 | 4.721 | -0.948 | -0.680 |
| fm_6_18 | 3.306 | -0.479 | 0.211 |
| fm_5_20 | 3.598 | 0.214 | 0.602 |
| fm_6_20 | 3.246 | -0.291 | 0.052 |
| fm_5_22 | 3.764 | -0.549 | -0.273 |
| fm_6_22 | 4.086 | 0.749 | 1.113 |
| fm_3_27 | 5.257 | 0.718 | 1.028 |
| fm_6_27 | 4.663 | 0.716 | 1.034 |
| fm_5_30 | 5.883 | 0.789 | 1.022 |
| fm_6_30 | 3.015 | -0.355 | 0.314 |
| fm_6_33 | 3.988 | 0.961 | 1.187 |
| fm_6_36 | 2.535 | 0.635 | 1.213 |
| fm_5_42 | 4.406 | 1.066 | 1.342 |
| fm_6_42 | 7.959 | 1.246 | 1.565 |
| fm_2_48 | 6.068 | 1.232 | 1.461 |
| fm_3_48 | 7.771 | 1.278 | 1.466 |
| fm_4_48 | 3.589 | 1.031 | 1.401 |
| fm_5_48 | 8.529 | 1.332 | 1.418 |
| fm_6_48 | 6.252 | 1.330 | 1.640 |
| fm_4_54 | 7.168 | 1.209 | 1.612 |
| fm_5_54 | 7.332 | 1.398 | 1.625 |
| fm_6_54 | 7.110 | 1.306 | 1.602 |
| fm_4_60 | 7.059 | 1.459 | 1.703 |
| fm_6_60 | 8.718 | 1.444 | 1.634 |
| fm_5_60 | 8.010 | 1.513 | 1.721 |
mirt package did not compute a valid model when missing data were present. Its coefficient results should be seen carefully.
mirt package could compute a model when the dataset had artificial imputation (2s and 0s), but it failed to achieve the M2 statistics.
The following code repeats the process described in the beginning.
#Slice the data
cg_items_na <- cg_original %>%
select(cg_floor:cg_30_p) #get all ASQ-I items
#change names
cg_items_na <- cg_items_na %>%
rename_at(vars(-cg_floor, -cg_ceiling),function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to understand
#change str for numeric
cg_items_na <- cg_items_na %>%
mutate_at(vars(cg_floor, cg_ceiling), list(~as.numeric(.))) #now, all variables are numeric
#replace na with the first/last option possible
#if the floor or the ceiling were missing, I'll fix it.
cg_items_na <- cg_items_na %>%
mutate_at(vars(cg_floor), list(~if_else(is.na(.),1,.)))
cg_items_na <- cg_items_na %>%
mutate_at(vars(cg_ceiling), list(~if_else(is.na(.),82,.)))
#locate floor and ceiling
#This function will replace the values before and after with NA
altMask <- function(x, val, low, high){
sapply(1:length(x), function(idx){
ifelse(between(x[idx], low[idx], high[idx]), val[idx], NA)
})
}
#Now I'll run the function
cg_items_na %>%
mutate(rowIdx = 1:n()) %>%
gather(col, value, starts_with("y")) %>%
mutate(value = altMask(parse_number(col), value, cg_floor, cg_ceiling)) %>%
spread(col, value) %>%
arrange(rowIdx) %>%
select(-rowIdx) -> cg_items_na
#Order
cg_items_na <- cg_items_na %>% select(cg_floor, cg_ceiling, paste("y", seq(1, ncol(select(., starts_with("y"))), 1), sep=""), everything())
#supress floor and ceiling
cg_items_na <- cg_items_na %>% select(-cg_floor, -cg_ceiling)
#check
plot_missing(cg_items_na)
The plot below shows the missing quantity in this domain:
I’ll run the IRT model.
#run the model
set.seed(123)
mod_cg_na <- mirt(cg_items_na, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_cg_na <- M2(mod_cg_na, type="C2", calcNull = FALSE, na.rm=TRUE)
Unfortunately, the M2 was not computed.
#replace NA by -99
cg_items_na <- cg_items_na %>%
mutate_all(., funs(replace_na(., -9)))
write.table(cg_items_na, file = "cg_items_na.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
Now I’ll test the dataset with the artificial imputation (2s and 0s). Note this dataset has no missing data.
#get entire data
cg_items_c_artificial <- cg_original %>%
select(cg_floor:cg_30_p) #get all ASQ-I items
#select specific items
items_up60 <- c("cg_1_2","cg_2_2","cg_3_2","cg_4_2","cg_5_2","cg_6_2","cg_4_4","cg_5_4","cg_1_6","cg_2_6","cg_3_6","cg_4_6","cg_5_6","cg_6_6","cg_5_8","cg_6_8","cg_4_10","cg_5_10","cg_6_10","cg_4_12","cg_5_12","cg_6_12","cg_4_14","cg_5_14","cg_6_14","cg_5_16","cg_6_16","cg_5_18","cg_6_18","cg_3_20","cg_4_20","cg_5_20","cg_6_20","cg_3_22","cg_4_24","cg_6_24","cg_3_27","cg_6_27","cg_5_30","cg_6_30","cg_5_36","cg_6_36","cg_5_42","cg_6_42","cg_3_48","cg_4_48","cg_6_48","cg_6_54","cg_5_54","cg_4_60","cg_6_60","cg_1_p","cg_2_p","cg_3_p","cg_4_p","cg_5_p","cg_6_p","cg_7_p","cg_8_p","cg_9_p","cg_10_p","cg_11_p","cg_12_p","cg_13_p","cg_14_p","cg_15_p","cg_16_p","cg_17_p","cg_18_p","cg_19_p","cg_20_p","cg_21_p","cg_22_p","cg_23_p","cg_24_p","cg_25_p","cg_26_p","cg_27_p","cg_28_p","cg_29_p","cg_30_p","cg_31_p")
cg_items_c_artificial <- cg_items_c_artificial %>%
select(items_up60)
cg_items_c_artificial <- cg_items_c_artificial %>%
select(-c(ends_with("_p")))
#check missing (should be 0)
plot_missing(cg_items_c_artificial)
# to flexmirt
write.table(cg_items_c_artificial, file = "cg_items_c_artificial.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
#run the model
set.seed(123)
mod_cg_artificial <- mirt(cg_items_c_artificial, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_cg_artificial <- M2(mod_cg_artificial, type="C2")
This model was acceptable. Its fit were: stats M2 1.777595e+03 df 1.224000e+03 p 0.000000e+00 RMSEA 2.428330e-02 RMSEA_5 2.176405e-02 RMSEA_95 2.669580e-02 SRMSR 1.385304e-01 TLI 9.958703e-01 CFI 9.960355e-01
coef(mod_cg_artificial, IRTpars=TRUE, simplify = TRUE) %>%
data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| cg_1_2 | 1.765 | -4.533 | -3.523 |
| cg_2_2 | 1.956 | -4.002 | -2.931 |
| cg_3_2 | 2.133 | -3.693 | -2.889 |
| cg_4_2 | 1.853 | -4.153 | -3.071 |
| cg_5_2 | 2.463 | -3.245 | -2.536 |
| cg_6_2 | 2.475 | -3.122 | -2.442 |
| cg_4_4 | 3.618 | -2.948 | -2.355 |
| cg_5_4 | 2.299 | -2.980 | -2.240 |
| cg_1_6 | 2.765 | -2.399 | -1.666 |
| cg_2_6 | 4.286 | -2.301 | -1.789 |
| cg_3_6 | 3.564 | -2.179 | -1.693 |
| cg_4_6 | 2.925 | -2.434 | -1.944 |
| cg_5_6 | 2.756 | -1.821 | -1.411 |
| cg_6_6 | 3.032 | -1.950 | -1.558 |
| cg_5_8 | 3.219 | -1.800 | -1.240 |
| cg_6_8 | 2.969 | -1.717 | -1.228 |
| cg_4_10 | 2.820 | -1.559 | -1.035 |
| cg_5_10 | 3.282 | -1.288 | -0.916 |
| cg_6_10 | 3.349 | -1.479 | -1.083 |
| cg_4_12 | 3.811 | -1.152 | -0.777 |
| cg_5_12 | 3.633 | -0.990 | -0.646 |
| cg_6_12 | 4.465 | -0.648 | -0.362 |
| cg_4_14 | 3.838 | -0.743 | -0.383 |
| cg_5_14 | 4.271 | -0.865 | -0.511 |
| cg_6_14 | 3.301 | -0.133 | 0.288 |
| cg_5_16 | 4.242 | -0.500 | -0.202 |
| cg_6_16 | 3.969 | -0.754 | -0.351 |
| cg_5_18 | 3.813 | 0.598 | 0.850 |
| cg_6_18 | 3.574 | -0.665 | -0.236 |
| cg_3_20 | 3.498 | -0.741 | -0.382 |
| cg_4_20 | 3.107 | -0.863 | -0.468 |
| cg_5_20 | 3.931 | -0.261 | 0.152 |
| cg_6_20 | 3.186 | -0.207 | 0.150 |
| cg_3_22 | 3.768 | -0.335 | 0.002 |
| cg_4_24 | 4.161 | -0.254 | 0.086 |
| cg_6_24 | 4.118 | -0.070 | 0.427 |
| cg_3_27 | 3.280 | -0.290 | 0.152 |
| cg_6_27 | 4.753 | 0.564 | 0.722 |
| cg_5_30 | 4.485 | 0.453 | 0.702 |
| cg_6_30 | 4.327 | 0.670 | 0.946 |
| cg_5_36 | 4.045 | 0.171 | 0.542 |
| cg_6_36 | 4.431 | 0.768 | 1.075 |
| cg_5_42 | 4.874 | 0.860 | 1.093 |
| cg_6_42 | 4.085 | 0.447 | 0.676 |
| cg_3_48 | 3.444 | 0.385 | 0.892 |
| cg_4_48 | 4.577 | 0.802 | 1.066 |
| cg_6_48 | 4.472 | 0.845 | 1.130 |
| cg_6_54 | 3.541 | 1.044 | 1.418 |
| cg_5_54 | 3.695 | 1.211 | 1.676 |
| cg_4_60 | 4.505 | 1.014 | 1.399 |
| cg_6_60 | 3.682 | 1.192 | 1.387 |
mirt package did not compute a valid model when missing data were present. Its coefficient results should be seen carefully.
mirt package could compute a model when the dataset had artificial imputation (2s and 0s). Its results allow conclude that this model is well-adjusted.
The following code repeats the process described in the beginning.
cm_original <- asqi_cm_online
#Slice the data
cm_items_na <- cm_original %>%
select(cm_floor:cm_18_p) #get all ASQ-I items
#change names
cm_items_na <- cm_items_na %>%
rename_at(vars(-cm_floor, -cm_ceiling),
function(x) paste0("y",seq(1:length(x)))) #rename items to make everything easier to understand
#change str for numeric
cm_items_na <- cm_items_na %>%
mutate_at(vars(cm_floor, cm_ceiling),
list(~as.numeric(.))) #now, all variables are numeric
# change items to 0,1 and 2
options(tibble.print_max = Inf)
#cm_items_na %>% select(-cm_floor, -cm_ceiling) %>% skimr::skim_to_list(.)
psych::describe(cm_items_na)
## vars n mean sd median trimmed mad min max range skew
## cm_floor 1 850 19.55 12.79 18 19.06 14.83 1 43 42 0.28
## cm_ceiling 2 666 33.86 11.99 32 32.84 10.38 6 67 61 0.74
## y1 3 850 1.94 0.29 2 2.00 0.00 0 2 2 -5.11
## y2 4 850 1.95 0.25 2 2.00 0.00 0 2 2 -5.87
## y3 5 850 1.94 0.29 2 2.00 0.00 0 2 2 -5.12
## y4 6 850 1.93 0.30 2 2.00 0.00 0 2 2 -4.63
## y5 7 850 1.96 0.21 2 2.00 0.00 0 2 2 -6.35
## y6 8 850 1.91 0.33 2 2.00 0.00 0 2 2 -3.70
## y7 9 850 1.94 0.29 2 2.00 0.00 0 2 2 -5.50
## y8 10 850 1.94 0.26 2 2.00 0.00 0 2 2 -4.64
## y9 11 850 1.90 0.35 2 2.00 0.00 0 2 2 -3.58
## y10 12 850 1.92 0.30 2 2.00 0.00 0 2 2 -4.13
## y11 13 850 1.87 0.42 2 2.00 0.00 0 2 2 -3.37
## y12 14 850 1.82 0.47 2 1.96 0.00 0 2 2 -2.74
## y13 15 850 1.76 0.57 2 1.90 0.00 0 2 2 -2.21
## y14 16 850 1.79 0.57 2 1.96 0.00 0 2 2 -2.58
## y15 17 850 1.66 0.61 2 1.79 0.00 0 2 2 -1.58
## y16 18 850 1.74 0.64 2 1.92 0.00 0 2 2 -2.16
## y17 19 850 1.71 0.53 2 1.81 0.00 0 2 2 -1.69
## y18 20 850 1.48 0.82 2 1.61 0.00 0 2 2 -1.10
## y19 21 850 1.59 0.75 2 1.74 0.00 0 2 2 -1.44
## y20 22 850 1.41 0.86 2 1.52 0.00 0 2 2 -0.90
## y21 23 850 1.38 0.87 2 1.48 0.00 0 2 2 -0.82
## y22 24 850 1.36 0.91 2 1.45 0.00 0 2 2 -0.76
## y23 25 850 1.29 0.91 2 1.36 0.00 0 2 2 -0.60
## y24 26 850 1.16 0.93 2 1.21 0.00 0 2 2 -0.33
## y25 27 850 1.12 0.97 2 1.15 0.00 0 2 2 -0.23
## y26 28 850 1.13 0.94 2 1.16 0.00 0 2 2 -0.26
## y27 29 850 1.12 0.95 2 1.15 0.00 0 2 2 -0.24
## y28 30 850 1.01 0.96 1 1.01 1.48 0 2 2 -0.01
## y29 31 850 1.08 0.95 1 1.10 1.48 0 2 2 -0.17
## y30 32 850 0.96 0.99 0 0.94 0.00 0 2 2 0.09
## y31 33 850 0.94 0.97 0 0.93 0.00 0 2 2 0.11
## y32 34 850 0.87 0.94 0 0.84 0.00 0 2 2 0.26
## y33 35 850 0.87 0.98 0 0.84 0.00 0 2 2 0.27
## y34 36 850 0.80 0.92 0 0.74 0.00 0 2 2 0.42
## y35 37 850 0.83 0.96 0 0.79 0.00 0 2 2 0.34
## y36 38 850 0.75 0.95 0 0.69 0.00 0 2 2 0.51
## y37 39 850 0.62 0.90 0 0.53 0.00 0 2 2 0.81
## y38 40 850 0.65 0.92 0 0.56 0.00 0 2 2 0.75
## y39 41 850 0.64 0.90 0 0.55 0.00 0 2 2 0.78
## y40 42 850 0.62 0.90 0 0.53 0.00 0 2 2 0.81
## y41 43 850 0.54 0.84 0 0.42 0.00 0 2 2 1.03
## y42 44 850 0.54 0.84 0 0.42 0.00 0 2 2 1.04
## y43 45 850 0.56 0.87 0 0.44 0.00 0 2 2 0.99
## y44 46 850 0.50 0.83 0 0.38 0.00 0 2 2 1.14
## y45 47 435 0.69 0.89 0 0.61 0.00 0 2 2 0.66
## y46 48 435 0.68 0.91 0 0.60 0.00 0 2 2 0.66
## y47 49 435 0.69 0.92 0 0.61 0.00 0 2 2 0.65
## y48 50 435 0.66 0.90 0 0.58 0.00 0 2 2 0.72
## y49 51 435 0.61 0.82 0 0.52 0.00 0 2 2 0.81
## y50 52 850 0.42 0.78 0 0.28 0.00 0 2 2 1.40
## y51 53 850 0.42 0.77 0 0.28 0.00 0 2 2 1.41
## y52 54 435 0.57 0.84 0 0.46 0.00 0 2 2 0.95
## y53 55 435 0.61 0.88 0 0.51 0.00 0 2 2 0.84
## y54 56 850 0.39 0.73 0 0.24 0.00 0 2 2 1.51
## y55 57 435 0.55 0.84 0 0.44 0.00 0 2 2 1.01
## y56 58 435 0.57 0.86 0 0.47 0.00 0 2 2 0.93
## y57 59 435 0.51 0.83 0 0.39 0.00 0 2 2 1.12
## y58 60 435 0.46 0.78 0 0.33 0.00 0 2 2 1.27
## y59 61 850 0.30 0.65 0 0.13 0.00 0 2 2 1.91
## y60 62 850 0.30 0.67 0 0.12 0.00 0 2 2 1.96
## y61 63 435 0.39 0.71 0 0.24 0.00 0 2 2 1.50
## y62 64 435 0.42 0.76 0 0.27 0.00 0 2 2 1.42
## y63 65 435 0.35 0.69 0 0.19 0.00 0 2 2 1.67
## y64 66 850 0.25 0.63 0 0.07 0.00 0 2 2 2.22
## y65 67 467 2.43 4.07 0 1.80 0.00 0 10 10 1.19
## y66 68 52 8.85 2.35 10 9.29 0.00 0 10 10 -1.78
## y67 69 52 9.81 0.97 10 10.00 0.00 5 10 5 -4.66
## y68 70 52 8.75 2.40 10 9.17 0.00 0 10 10 -1.63
## y69 71 52 8.65 2.64 10 9.17 0.00 0 10 10 -1.76
## y70 72 52 8.94 2.29 10 9.40 0.00 0 10 10 -1.96
## y71 73 52 8.65 2.99 10 9.40 0.00 0 10 10 -2.00
## y72 74 52 8.85 2.55 10 9.40 0.00 0 10 10 -2.07
## kurtosis se
## cm_floor -0.98 0.44
## cm_ceiling 0.12 0.46
## y1 26.91 0.01
## y2 36.71 0.01
## y3 27.22 0.01
## y4 22.42 0.01
## y5 43.88 0.01
## y6 14.10 0.01
## y7 30.86 0.01
## y8 22.98 0.01
## y9 12.99 0.01
## y10 17.87 0.01
## y11 10.72 0.01
## y12 6.66 0.02
## y13 3.63 0.02
## y14 5.05 0.02
## y15 1.32 0.02
## y16 2.92 0.02
## y17 1.93 0.02
## y18 -0.61 0.03
## y19 0.32 0.03
## y20 -1.05 0.03
## y21 -1.18 0.03
## y22 -1.35 0.03
## y23 -1.53 0.03
## y24 -1.76 0.03
## y25 -1.90 0.03
## y26 -1.82 0.03
## y27 -1.84 0.03
## y28 -1.91 0.03
## y29 -1.88 0.03
## y30 -1.97 0.03
## y31 -1.93 0.03
## y32 -1.83 0.03
## y33 -1.91 0.03
## y34 -1.70 0.03
## y35 -1.83 0.03
## y36 -1.70 0.03
## y37 -1.26 0.03
## y38 -1.39 0.03
## y39 -1.32 0.03
## y40 -1.28 0.03
## y41 -0.78 0.03
## y42 -0.79 0.03
## y43 -0.96 0.03
## y44 -0.59 0.03
## y45 -1.41 0.04
## y46 -1.46 0.04
## y47 -1.49 0.04
## y48 -1.37 0.04
## y49 -1.04 0.04
## y50 0.11 0.03
## y51 0.18 0.03
## y52 -0.92 0.04
## y53 -1.19 0.04
## y54 0.55 0.03
## y55 -0.83 0.04
## y56 -0.99 0.04
## y57 -0.60 0.04
## y58 -0.17 0.04
## y59 2.07 0.02
## y60 2.09 0.02
## y61 0.62 0.03
## y62 0.24 0.04
## y63 1.15 0.03
## y64 3.22 0.02
## y65 -0.44 0.19
## y66 2.32 0.33
## y67 20.12 0.13
## y68 1.72 0.33
## y69 2.19 0.37
## y70 3.06 0.32
## y71 2.69 0.41
## y72 3.43 0.35
#Replace 5 and 10 values to the righ code (5 equals 1, and 10 equals 2)
cm_items_na <- cm_items_na %>%
mutate_at(vars(-cm_floor, -cm_ceiling),
list(~case_when(. == 5 ~ 1, . == 10 ~ 2,
TRUE ~ .))) #changing values
#replace na with the first/last option possible
#if the floor or the ceiling were missing, I'll fix it.
cm_items_na <- cm_items_na %>%
mutate_at(vars(cm_floor), list(~if_else(is.na(.),1,.)))
cm_items_na <- cm_items_na %>%
mutate_at(vars(cm_ceiling), list(~if_else(is.na(.),72,.)))
#Now I'll run the function I've created
cm_items_na %>%
mutate(rowIdx = 1:n()) %>%
gather(col, value, starts_with("y")) %>%
mutate(value = altMask(parse_number(col), value, cm_floor, cm_ceiling)) %>%
spread(col, value) %>%
arrange(rowIdx) %>%
select(-rowIdx) -> cm_items_na
#Order
cm_items_na <- cm_items_na %>% select(cm_floor, cm_ceiling, paste("y", seq(1, ncol(select(., starts_with("y"))), 1), sep=""), everything())
#supress floor and cm_items
cm_items_na <- cm_items_na %>% select(-cm_floor, -cm_ceiling)
#chcking missing quantity
plot_missing(cm_items_na)
The plot below shows the missing quantity in this domain:
I’ll run the IRT model.
#run the model
set.seed(123)
mod_cm_na <- mirt(cm_items_na, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_cm_na <- M2(mod_cg_na, type="C2", calcNull = FALSE, na.rm=TRUE)
#replace NA by -99
cm_items_na <- cm_items_na %>%
mutate_all(., funs(replace_na(., -9)))
write.table(cm_items_na, file = "cm_items_na.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
Now I’ll test the dataset with the artificial imputation (2s and 0s). Note this dataset has no missing data.
cm_original <- asqi_cm_online
#get entire data
cm_items_c_artificial <- cm_original %>%
select(cm_floor:cm_18_p) #get all ASQ-I items
#Slice the data
items_up60 <- c(
"cm_1_2",
"cm_2_2",
"cm_3_2",
"cm_4_2",
"cm_5_2",
"cm_6_2",
"cm_3_4",
"cm_4_4",
"cm_5_4",
"cm_6_4",
"cm_2_6",
"cm_3_6",
"cm_4_6",
"cm_5_6",
"cm_6_6",
"cm_5_8",
"cm_6_8",
"cm_4_10",
"cm_5_10",
"cm_6_10",
"cm_5_12",
"cm_6_12",
"cm_3_14",
"cm_4_14",
"cm_5_14",
"cm_6_14",
"cm_5_16",
"cm_6_16",
"cm_4_20",
"cm_5_20",
"cm_3_22",
"cm_5_18",
"cm_6_18",
"cm_4_22",
"cm_5_22",
"cm_6_27",
"cm_5_27",
"cm_6_30",
"cm_5_33",
"cm_6_33",
"cm_6_36",
"cm_5_42",
"cm_6_42",
"cm_1_48",
"cm_2_48",
"cm_3_48",
"cm_4_48",
"cm_5_54",
"cm_6_54",
"cm_6_60",
"cm_4_60",
"cm_1_p",
"cm_2_p",
"cm_3_p",
"cm_4_p",
"cm_5_p",
"cm_6_p",
"cm_7_p",
"cm_8_p",
"cm_9_p",
"cm_10_p",
"cm_11_p",
"cm_12_p",
"cm_13_p",
"cm_14_p",
"cm_15_p",
"cm_16_p",
"cm_17_p",
"cm_18_p",
"cm_19_p",
"cm_20_p",
"cm_21_p")
cm_items_c_artificial <- cm_items_c_artificial %>%
select(items_up60)
cm_items_c_artificial <- cm_items_c_artificial %>%
dplyr::select(-c("cm_4_48",ends_with("_p")))
#check
plot_missing(cm_items_c_artificial)
# to flexmirt
write.table(cm_items_c_artificial, file = "cm_items_c_artificial.dat", row.names=FALSE, col.names = FALSE, sep = "\t", quote = FALSE)
#run the model
set.seed(123)
mod_cm_artificial <- mirt(cm_items_c_artificial, 1, itemtype = "graded", method = "MHRM", technical=list(NCYCLES=2000))
#check the fit statistics
m2_cm_artificial <- M2(mod_cm_artificial, type="C2")
The model had an excellent fit. 2706.1340152, 1175, 0, 0.0391772, 0.0372195, 0.0410919, 0.0918224, 0.9901948, 0.990595. The coefficients are reported in the next table.
coef(mod_cm_artificial, IRTpars=TRUE, simplify = TRUE) %>%
data.frame(.) %>%
select(-means, -F1) %>%
kable(., digits = 3) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| items.a | items.b1 | items.b2 | |
|---|---|---|---|
| cm_1_2 | 1.837 | -3.481 | -2.635 |
| cm_2_2 | 3.489 | -2.927 | -2.214 |
| cm_3_2 | 2.934 | -3.080 | -1.958 |
| cm_4_2 | 2.747 | -3.623 | -2.568 |
| cm_5_2 | 2.445 | -2.655 | -1.912 |
| cm_6_2 | 2.631 | -3.374 | -2.480 |
| cm_3_4 | 2.075 | -2.657 | -1.153 |
| cm_4_4 | 2.334 | -3.300 | -2.320 |
| cm_5_4 | 4.165 | -2.764 | -2.256 |
| cm_6_4 | 3.091 | -3.391 | -2.189 |
| cm_2_6 | 1.993 | -2.694 | -1.766 |
| cm_3_6 | 3.074 | -2.921 | -1.884 |
| cm_4_6 | 3.278 | -3.098 | -2.021 |
| cm_5_6 | 3.438 | -1.928 | -1.604 |
| cm_6_6 | 2.532 | -2.086 | -1.025 |
| cm_5_8 | 2.797 | -2.110 | -1.390 |
| cm_6_8 | 3.874 | -1.695 | -1.450 |
| cm_4_10 | 3.851 | -1.207 | -0.832 |
| cm_5_10 | 4.918 | -0.999 | -0.654 |
| cm_6_10 | 3.951 | -0.880 | -0.690 |
| cm_5_12 | 4.170 | -1.046 | -0.726 |
| cm_6_12 | 3.796 | -0.824 | -0.478 |
| cm_3_14 | 3.425 | -0.641 | -0.226 |
| cm_4_14 | 3.332 | -1.448 | -1.035 |
| cm_5_14 | 5.773 | -0.427 | -0.273 |
| cm_6_14 | 5.153 | -0.523 | -0.183 |
| cm_5_16 | 5.508 | 0.091 | 0.301 |
| cm_6_16 | 6.665 | -0.096 | -0.001 |
| cm_4_20 | 5.173 | -0.126 | 0.086 |
| cm_5_20 | 4.473 | -0.556 | -0.175 |
| cm_3_22 | 4.604 | -0.299 | 0.029 |
| cm_5_18 | 4.413 | -0.454 | -0.118 |
| cm_6_18 | 7.031 | 0.265 | 0.437 |
| cm_4_22 | 6.583 | 0.080 | 0.167 |
| cm_5_22 | 4.990 | 0.501 | 0.738 |
| cm_6_27 | 4.623 | -0.043 | 0.332 |
| cm_5_27 | 8.091 | 0.522 | 0.745 |
| cm_6_30 | 6.262 | 0.506 | 0.772 |
| cm_5_33 | 4.159 | 0.076 | 0.521 |
| cm_6_33 | 5.115 | 0.498 | 0.679 |
| cm_6_36 | 3.847 | 1.261 | 1.553 |
| cm_5_42 | 4.401 | 0.641 | 1.037 |
| cm_6_42 | 7.449 | 0.944 | 1.349 |
| cm_1_48 | 6.503 | 0.775 | 1.046 |
| cm_2_48 | 5.674 | 0.660 | 1.007 |
| cm_3_48 | 7.106 | 0.918 | 1.249 |
| cm_5_54 | 7.224 | 0.705 | 0.884 |
| cm_6_54 | 6.744 | 0.956 | 1.217 |
| cm_6_60 | 6.038 | 1.144 | 1.551 |
| cm_4_60 | 4.077 | 1.372 | 1.620 |
mirt package did not compute a valid model when missing data were present. Its coefficient results should be seen carefully.
mirt package could compute a model when the dataset had artificial imputation (2s and 0s). Its results allow conclude that this model is well-adjusted.