plot.D3mirt {D3mirt}R Documentation

Plot Method for Objects of Class D3mirt

Description

For graphing of objects of class D3mirt from the D3mirt() function using the rgl 3D visualization device system (Adler & Murdoch, 2022).

Usage

## S3 method for class 'D3mirt'
plot(
  x,
  scale = FALSE,
  hide = FALSE,
  diff.level = NULL,
  items = NULL,
  item.names = TRUE,
  item.lab = NULL,
  constructs = FALSE,
  construct.lab = NULL,
  adjust.lab = c(0.5, -0.8),
  x.lab = "X",
  y.lab = "Y",
  z.lab = "Z",
  title = "",
  line = -5,
  axis.scalar = 1.1,
  axis.length = NULL,
  axis.col = "black",
  axis.points = "black",
  points = TRUE,
  axis.ticks = TRUE,
  nticks = 4,
  width.rgl.x = 1040,
  width.rgl.y = 1040,
  view = c(15, 20, 0.6),
  show.plane = TRUE,
  plane.col = "grey80",
  background = "white",
  type = "rotation",
  col = c("black", "grey20", "grey40", "grey60", "grey80"),
  arrow.width = 0.6,
  n = 20,
  theta = 0.2,
  barblen = 0.03,
  c.scalars = c(1, 1),
  c.type = "rotation",
  c.col = "black",
  c.arrow.width = 0.6,
  c.n = 20,
  c.theta = 0.2,
  c.barblen = 0.03,
  profiles = NULL,
  levels = NULL,
  sphere.col = c("black", "grey20", "grey40", "grey60", "grey80"),
  spheres.r = 0.05,
  ci = FALSE,
  ci.level = 0.95,
  ellipse.col = "grey80",
  ellipse.alpha = 0.2,
  ...
)

Arguments

x

A S3 object of class D3mirt.

scale

Logical, if item vector arrow length should visualize the MDISC. If set to FALSE, the vector arrow length will be of one unit length. The default is scale = FALSE.

hide

Logical, if items should be plotted. The default is hide = FALSE.

diff.level

Optional. Plotting of a single level of difficulty indicated by an integer.

items

Optional. The user can input a list of integers indicating what item vector arrows will be visible while the remaining item vector arrows are hidden.

item.names

Logical, if item labels should be plotted. The default is item.names = TRUE.

item.lab

Optional. String vector of item names that will override row names extracted from the data frame. Note, row names are not overwritten. Instead, the string vector in ìtem.lab prints item labels on the item vector arrows currently displayed following the order of item vector arrows in the graphical output. For example, when plotting in the default mode (plotting all item vectors) the labels will follow the order of the items in the data frame. If a selection of items is plotted with items, e.g., ìtems = c(24,34,25), then the item labels will be displayed following the order of the vector in items left to right. In this case, item label 1 will be printed on item 24, item label 2 on item 34, and item label 3 on item 25, and so on.

constructs

Logical, if construct vector arrows should be plotted. The default is constructs = FALSE.

construct.lab

Optional. String vector of names for constructs, similar to item.lab.

adjust.lab

Vector of parameters for the position of the item and construct labels for the text3d function. The first value is for horizontal adjustment and the second is for vertical adjustment. The default is adjust.lab = c(0.5, -0.8).

x.lab

Labels for x-axis, the default is x.lab = "X".

y.lab

Labels for y-axis, the default is y.lab = "Y".

z.lab

Labels for y-axis, the default is z.lab = "Z".

title

The main title for the graphical device, plotted with the title3d() function. The default is no title.

line

Title placement for title3d(). The default is line = -5.

axis.scalar

Scalar multiple for adjusting the length of all axes (x, y, z) in the 3D model proportionally. The default is axis.scalar = 1.1.

axis.length

Optional. For adjusting the length of the axis manually by entering a numeric or a numeric vector. For instance, c(3,2,4,3,3,2) indicate axis coordinates x = 3, -x = 3, y = 4, -y = 3, z = 3, -z = 2. Note, a symmetric model can be created easily by adding a single numeric in the axis.length argument (e.g., axis.length = 4) because the function repeats the last value in the vector to cover all axis points. The default is axis.length = NULL.

axis.col

Color of axis for the segment3D()function, the default is axis.col = "black".

axis.points

Color of axis points for the points3d() function. The default is axis.points = "black".

points

Logical, if axis from points3d() should have end points. The default is points = TRUE.

axis.ticks

Logical, if axis ticks from the axis3d() function should be plotted. The default is axis.ticks = TRUE.

nticks

Number of ticks for axis3d(). The function repeats the last numeric value in the vector to cover all axis. The user can, therefore, adjust the number of ticks with one numeric value (e.g., nticks = 6) or up to three (e.g., nticks = c(6,4,8) corresponding to the for the x, y, and z axes respectively. The default is nticks = 4.

width.rgl.x

Width in the x direction for par3d(). The default is width.rgl.x = 1040.

width.rgl.y

Width in the y direction for par3d(). The default is width.rgl.y = 1040.

view

Vector with polar coordinates and zoom factor for the view3d function. The default is view = c(15,20, 1).

show.plane

Logical, if xz-plane should be visible in the graphical device. The default is show.plane = TRUE.

plane.col

Color of the plane, the default is plane.col = "grey80".

background

Set background color for the graphical device, the default is background = "white".

type

Type of vector arrow for items, the default is type = "rotation". See rgl::arrow3d for more options regarding arrow types.

col

Vector of colors representing difficulty levels for item response functions used in arrow3d(). The default is col = c("black", "grey20", "grey40", "grey60", "grey80").

arrow.width

Width of vector arrows for arrow3d(). The default is arrow.width = 0.6.

n

Number of barbs for the vector arrows from arrow3d(). The default is n = 20.

theta

Opening angle of barbs for vector arrows from arrow3d(). The default is theta = 0.2.

barblen

The length of the barbs for vector arrows from arrow3d(). The default is barblen = 0.03.

c.scalars

Set of scalars for adjusting construct arrow length proportionally. The first numeric adjusts the length in the positive direction and the second numeric the length in the negative direction. The default is c.scalars = c(1,1).

c.type

Type of vector arrow for constructs. See rgl::arrow3d for more options regarding arrow types. The default is c.type = "rotation".

c.col

Color of construct vector arrows from arrow3d(), the default is c.col = "black".

c.arrow.width

Width of construct vector arrows for arrow3d(). The default is c.arrow.width = 0.6.

c.n

Number of barbs for the construct vector arrows from the arrow3d() function. The default is c.n = 20.

c.theta

Opening angle of barbs for construct vector arrows from arrow3d(). The default is c.theta = 0.2.

c.barblen

The length of the barbs for construct vector arrows from arrow3d(). The default is c.barblen = 0.03.

profiles

Data frame with coordinates for spheres representing respondent scores. The default is profiles = NULL.

levels

Optional. A column with values indicating levels for sphere colors from the sphere.col vector. The default is levels = NULL.

sphere.col

Color vector for spheres3d(). The default is sphere.col = c("black", "grey20", "grey40", "grey60", "grey80").

spheres.r

Radius of the spheres for spheres3d(). The default is spheres.r = 0.05.

ci

Logical, if spheres should include an ellipsoid outlining a confidence region returned from the ellipse3d() function. The default is ci = FALSE.

ci.level

Level of confidence for ellipse3d(), the default is ci.level = 0.95.

ellipse.col

Color of the ellipse from ellipse3d(). The default is ellipse.col = "grey80".

ellipse.alpha

Opacity for the confidence region from ellipse3d(). The default is ellipse.alpha = 0.20.

...

Additional arguments passed to RGL or methods.

Details

The plotting function allows plotting of all items, a selection of items as well as plotting a single item. Length of the vector arrows can be set to one unit length across all item vector arrows by setting scale = TRUE. This removes the visualization of the MDISC parameter. Note, when scaling items with scale = TRUE, the plot() function does not change the length of the model axes. This often means that the axes of the model may need to be adjusted, which can be achieved proportionally with axis.scalar or manually with axis.length.

The user also has the option of adding constructs to the graphical output with constructs = TRUE (see the documentation for D3mirt or the package vignette regarding constructs). Other options include plotting one level of difficulty at a time with the diff.level argument if polytomous items are used in the model. Item row names are displayed by default, but the user has the option of adding new item labels for the items with item.lab, as well as labeling constructs with construct.lab.

Regarding the interpretation of results, the angle of the vector arrows indicates what traits, located along the orthogonal axes, an item can be said to describe (Reckase, 2009, 1985, Reckase & McKinley, 1991). For instance, an item located at 0° seen from the x-axis, and 90° as seen from the y and z-axis, only describes trait x. Such an item is unidimensional since its direction vector lies parallel and on the x-axis. In contrast, an item located at 45° between all three axes in a three-dimensional model describes all three traits in the model equally well. Such an item is within-multidimensional with respect to all three latent traits used in the analysis because its direction vector points in a neutral direction in the model.

When plotting the D3mirt model with plot(), it is possible to visually observe statistical violations in the graphical output returned. For instance, shorter vector arrows indicate weaker discrimination and therefore also higher amounts of statistical violations. Moreover, if a polytomous item struggles or even fail to describe any of the latent variables in the model, it can often lead to an extreme stretch of the MDIFF range. This is comparable to trace lines turning horizontal in a unidimensional item response theory model.

The plot function can also display respondent scores in the three-dimensional model space, represented as spheres whose coordinates are derived from the respondent's factor scores. This allows for a profile analysis in which respondent rows are separated or selected conditioned on some external criteria. To do this, the user must first extract respondent factor scores with mirt::fscores(Chalmers, 2012) and then use some selection process to separate or subset respondent rows. The resulting data frame is used in the profiles argument. If desired, a confidence interval can be added to the spheres by setting ci = TRUE. A general advice is also to hide vector arrows with hide = TRUE when analyzing respondent profiles to avoid visual cluttering. For more on profile analysis (e.g., preparation and examples), see package vignette.

The returned RGL device can, for example, be exported to the R console and be saved as an interactive html file or as a still shoot (see examples below). In the case of the latter, the model perspective in the still shoot can be manually adjusted by changing the view argument for the function.

Value

A RGL graphical device.

Author(s)

Erik Forsberg

References

Adler, D., & Murdoch, D. (2022). Rgl: 3d Visualization Using OpenGL Computer software.

Chalmers, R., P. (2012). mirt: A Multidimensional Item Response Theory Package for the R Environment. Journal of Statistical Software, 48(6), 1-29.

Reckase, M. D. (2009). Multidimensional Item Response Theory. Springer.

Reckase, M. D. (1985). The Difficulty of Test Items That Measure More Than One Ability. Applied Psychological Measurement, 9(4), 401-412. https://doi-org.ezp.sub.su.se/10.1177/014662168500900409

Reckase, M. D., & McKinley, R. L. (1991). The Discriminating Power of Items That Measure More Than One Dimension. Applied Psychological Measurement, 15(4), 361-373. https://doi-org.ezp.sub.su.se/10.1177/014662169101500407

Examples


# To plot, the data must be prepared with mirt::mirt and the D3mirt() function
# Load data
data("anes0809offwaves")
x <- anes0809offwaves
x <- x[,3:22] # Remove columns for age and gender

# Fit a three-dimensional graded response model with orthogonal factors
spec <- '  F1 = 1-20
           F2 = 1-20
           F3 = 1-20

           START=(W7Q3,a2,0)
           START=(W7Q3,a3,0)

           START=(W7Q20,a3,0)

           FIXED=(W7Q3,a2)
           FIXED=(W7Q3,a3)

           FIXED=(W7Q20,a3) '


mod1 <- mirt::mirt(x,
                   spec,
                   itemtype = 'graded',
                   SE = TRUE,
                   method = 'QMCEM')

# Optional: Load the mod1 data for this example directly from the package file
# load(system.file("extdata/mod1.Rdata", package = "D3mirt"))

# Call D3mirt() with mod1 and constructs assigned to c
c <- list(list(1,2,3,4,5,6,7,8,9,10),
          list(11,12,13,14),
          list(15,17,18,19,20))
g <- D3mirt(mod1, c)
plot(g)

# Plot RGL device with constructs visible and named
plot(g, constructs = TRUE,
     construct.lab = c("Compassion", "Fairness", "Conformity"))

# Item W7Q16 has location 6 in the data set (gender and age excluded)
# The item is plotted together with construct to aid the visual interpretation
plot(g, constructs = TRUE,
     items = 6,
     construct.lab = c("Compassion", "Fairness", "Conformity"))

# Plot RGL device on item difficulty level 5
plot(g, diff.level = 5)

# A selection of Conformity items from the model plotted with constructs
plot(g, constructs = TRUE,
     items = c(5,7,8,9,10),
     construct.lab = c("Compassion", "Fairness", "Conformity"))

# Plot RGL device with scaled items and constructs visible and named
plot(g, scale = TRUE,
     constructs = TRUE,
     construct.lab = c("Compassion", "Fairness", "Conformity"))

# Profile Analysis
# Extract respondent factor scores from mod1 (see D3mirt()) with fscores()
f <- mirt::fscores(mod1,
                   method="EAP",
                   full.scores = TRUE,
                   full.scores.SE = FALSE, QMC = TRUE)

# Optional: Load the respondent factor scores for this example directly from the package file
# load(system.file("extdata/fscores.Rdata", package = "D3mirt"))

# Attach f to the gender variable (column 2 from anes0809offwaves data set; "W3XGENDER")
# Use cbind with fscores() output attached first
x <- anes0809offwaves
z <- data.frame(cbind(f, x[,2]))

# Plot profiles with item vector arrows hidden
# Score levels: 1 = Blue ("male") and 2 = Red ("female")
plot(g, hide = TRUE,
     profiles = z,
     levels = z[,4],
     sphere.col = c("blue", "red"),
     x.lab = "Compassion",
     y.lab="Conformity",
     z.lab="Fairness")

# Add a 95% CI to respondent factor scores on <= 30 y.o.
# Column bind fscores() with age variable ("W3Xage")
y <- data.frame(cbind(f, x[,1]))

# Subset data frame y conditioned on age <= 30
z1 <- subset(y, y[,4] <= 30)

# Use rep() to create a color vector to color groups based on the nlevels() output
# z1 has 14 factor levels
colvec <- c(rep("red", 14))

# Call plot() with profile data on age with item vector arrows hidden
plot(g, hide = TRUE,
     profiles = z1,
     levels = z1[,4],
     sphere.col = colvec,
     x.lab = "Compassion",
     y.lab="Conformity",
     z.lab="Fairness",
     ci = TRUE,
     ci.level = 0.95,
     ellipse.col = "orange")

## Not run: 
# Export an open RGL device to the console to be saved as html or image file
plot(g, constructs = TRUE)
s <- scene3d()
rgl::rglwidget(s,
               width = 1040,
               height = 1040)

# Export a snap shoot of an open RGL device directly to file
plot(g, constructs = TRUE)
rgl::rgl.snapshot('RGLdevice.png',
                    fmt = 'png')

## End(Not run)

[Package D3mirt version 1.1.0 Index]