Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ README.html
^build_package\.R$
^project-docs$
^.*\.Rcheck$
^ValCont\.code-workspace$
38 changes: 37 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,43 @@ jobs:

- name: Build source archive
shell: bash
run: Rscript build_package.R --no-manual
run: |
set -euo pipefail
Rscript - <<'RSCRIPT'
description <- read.dcf("DESCRIPTION")
package_name <- unname(description[1L, "Package"])
package_version <- unname(description[1L, "Version"])
expected_archive <- sprintf("%s_%s.tar.gz", package_name, package_version)

existing_archives <- list.files(
pattern = sprintf("^%s_%s\\.tar\\.gz$", package_name, package_version)
)
if (length(existing_archives) > 0L) {
unlink(existing_archives, force = TRUE)
}

r_executable <- file.path(R.home("bin"), "R")
status <- system2(
r_executable,
args = c("CMD", "build", "--no-manual", ".")
)
if (!identical(status, 0L)) {
stop(sprintf("R CMD build failed with status %d.", status))
}

archives <- list.files(
pattern = sprintf("^%s_%s\\.tar\\.gz$", package_name, package_version)
)
if (length(archives) != 1L || !identical(archives[[1L]], expected_archive)) {
stop(sprintf(
"Expected exactly one archive named %s, found: %s",
expected_archive,
paste(archives, collapse = ", ")
))
}

cat(sprintf("Created %s\\n", expected_archive))
RSCRIPT

- name: Upload source archive as workflow artifact
uses: actions/upload-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ validate_package.R
build_package.R
AGENTS.md
/project-docs/
ValCont.code-workspace
2 changes: 2 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Authors@R: c(
comment = c(ORCID = "0000-0002-2107-3140")
)
)
Author: Cesar Merino-Soto [aut, ctb, rev] (ORCID: <https://orcid.org/0000-0001-8049-7069>), Jose Livia Segovia [aut, ctb] (ORCID: <https://orcid.org/0000-0003-2226-3349>), Diego Livia Ortiz [aut, cre, ctb, rev] (ORCID: <https://orcid.org/0000-0002-2107-3140>)
Maintainer: Diego Livia Ortiz <diegolivia@hotmail.com>
Description: Provides tools for content validity studies, including functions to calculate content validity coefficients from ratings by expert or experiential judges. It implements CVC(), CVI(), CVIR(), CVR(), and Vaiken() together with asymmetric confidence intervals for bounded coefficients and methods for comparing independent coefficients. The methods are based on Aiken (1980, 1985) <doi:10.1177/001316448004000419>, Wilson (1927) <doi:10.2307/2276774>, and Merino-Soto (2018) <doi:10.6018/analesps.34.3.283481>.
License: GPL (>= 3)
URL: https://github.com/Diegolivia/ValCont
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export(CVRcut.Ayres)
export(CVRcut.Bag)
export(CVRcut.Wilson)
export(CVplot)
export(ColquittHT)
export(D2)
export(HTmult)
export(Haiken)
Expand Down Expand Up @@ -47,12 +48,14 @@ importFrom(ggplot2,
importFrom(rlang,.data)
importFrom(stats,
complete.cases,
median,
na.omit,
pbeta,
pbinom,
pnorm,
qnorm,
qt,
quantile,
sd
)
importFrom(utils,combn)
8 changes: 6 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- `MDScontent()` for multidimensional scaling maps of item-trait correspondence.
- `LuAgree()` for estimating Lu's agreement coefficient.
- `ColquittHT()` for Colquitt's content validity approach.
- `Haiken()` for Aiken's coefficient of homogeneity with bootstrap confidence intervals.
- `HTmult()` for Hinkin-Tracey indices.
- `minimumCV()` for Wilson-based minimum sample-size or critical-value calculations.
- Additional public and supporting functions for content validity analyses, including `CVIpub()` and `Vaikenpub()`.
Expand All @@ -14,15 +16,17 @@
### Changed

- Added explicit validation for missing data across the package functions.
- Refactored MER confidence-interval calculations and improved code consistency.
- Refactored confidence-interval calculations for MER, Aiken's V, CVI, CVR, and related coefficients.
- Expanded and improved content validity calculations across CVC, CIR, CVI, CVIR, CVR, and SVAL functions.
- Improved plotting support using `ggplot2` and added MDS plotting functionality.
- Expanded and regenerated package documentation.
- Updated package metadata, namespace exports, dependencies, and repository documentation.
- Updated package metadata, namespace exports, dependencies, README, and repository documentation.

### Fixed

- Corrected documentation, namespace, and package-structure issues identified during CRAN-style validation.
- Improved handling of package examples and test execution.
- Added package build exclusions and validation checks for clean source-package archives.

## ValCont 0.1.0

Expand Down
40 changes: 19 additions & 21 deletions R/CID.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,18 @@
#'`CID` uses Method of Variance Estimates Recovery (MOVER; Zou, & Donner, 2008).
#'Because data produced by judges' judgments tend to be asymmetrically distributed (if the item is rated, on a scale of 1 to 5, as predominantly valid then its values will be > 3), MOVER is appropriate for non-normal distributions.
#'MOVER depends on the quality or precision of the confidence intervals calculated for the coefficients in each group.
#'The application of MOVER for content validity coefficient was initially published by Merino-Soto (2018) for the difference between V coefficients (Aiken, 1980, 1985). Later, Merino-Soto (2023) extended this approach for Aiken's V by adding a point estimator of the difference, based on the standardized difference between proportions
#'The application of MOVER for content validity coefficient was initially published by Merino-Soto (2018) for the difference between V coefficients (Aiken, 1980, 1985). Later, Merino-Soto (2023) extended this approach for Aiken's V by adding a point estimator of the difference, based on the standardized difference between proportions.
#'The compared content validity coefficients obtained should be of the same type, and the estimated confidence intervals for these coefficients should also come from the same level; for example, at .95 or .90.
#'Singer (2010) observed that at extremely low values (e.g., proportions near .0), the coverage of this method is not as good. In the context of comparing content validity coefficients, treated as proportions, it is rare to find such low coefficients (and their confidence intervals). Unless the items are extremely poor in content.
#'
#'Note: The function has not yet been prepared to resolve missing values, so the user must remove or impute any missing values.
#'Singer (2010) observed that at extremely low values (e.g., proportions near .0), the coverage of this method is not as good. In the context of comparing content validity coefficients, treated as proportions, it is rare to find such very low coefficients (and their confidence intervals). Unless the items are extremely poor in content.
#'
#'@references
#'Aiken, L. R. (1980). Content validity and reliability of single items or questionnaires. Educational and. Psychological Measurement, 40, 955-959. https://doi.org/10.1177/001316448004000419
#'Aiken, L. R. (1980). Content validity and reliability of single items or questionnaires. \emph{Educational and. Psychological Measurement, 40}, 955-959. \doi{10.1177/001316448004000419}
#'
#'Aiken, L. R. (1985). Three coefficients for analyzing the reliability and validity of ratings. Educational and Psychological Measurement, 45, 131-142. https://doi.org/10.1177/0013164485451012
#'Aiken, L. R. (1985). Three coefficients for analyzing the reliability and validity of ratings. \emph{Educational and Psychological Measurement, 45}, 131-142. \doi{10.1177/0013164485451012}
#'
#'Merino-Soto, C. (2018) Confidence interval for difference between coefficients of content validity (Aiken's V): a SPSS syntax. Anales de Psicologia, 34(3), 587-590. https://doi.org/10.6018/analesps.34.3.283481
#'Merino-Soto, C. (2018) Confidence interval for difference between coefficients of content validity (Aiken's V): a SPSS syntax. \emph{Anales de Psicologia, 34}(3), 587-590. \doi{10.6018/analesps.34.3.283481}
#'
#'Merino-Soto, C. (2023). Coeficientes V de Aiken: diferencias en los juicios de validez de contenido. MHSalud, 20(1), 23-32. https://doi.org/10.15359/mhs.20-1.3
#'Merino-Soto, C. (2023). Coeficientes V de Aiken: diferencias en los juicios de validez de contenido. \emph{MHSalud, 20}(1), 23-32. \doi{10.15359/mhs.20-1.3}
#'
#'Singer, J. (2010). Construction of confidence limits about effect measures: A general approach, by G. Y. Zou and A. Donner, Statistics in Medicine 2008; 27:1693-1702. Statistics in Medicine, 29(16), 1757-1759. https://doi.org/10.1002/sim.3887
#'
Expand Down Expand Up @@ -99,34 +97,34 @@
#' lwr.col = "lwr.ci",
#' upr.col = "upr.ci")
#'
#'
#'
#'@export
CID <- function(group1, group2, coef.col = "coef", lwr.col = "lwr.ci", upr.col = "upr.ci", na.rm = FALSE) {
# Validar que los argumentos son data.frames
# Verify that the arguments are DataFrames
if (!is.data.frame(group1) || !is.data.frame(group2)) {
stop("Ambos argumentos 'group1' y 'group2' deben ser data.frames.")
stop("Both the 'group1' and 'group2' arguments must be data.frames.")
}

# Deteccion de valores perdidos
# Detection of Missing Values
if (!na.rm) {
if (any(is.na(group1)) || any(is.na(group2))) {
stop("Valores perdidos detectados. Usa na.omit() primero o establece na.rm=TRUE.")
stop("Missing values detected. Use na.omit() first, or set na.rm=TRUE.")
}
} else {
group1 <- na.omit(group1)
group2 <- na.omit(group2)
}

# Validar que las columnas necesarias existen en los data.frames
# Verify that the necessary columns exist in the data frames
required_cols <- c(coef.col, lwr.col, upr.col)
if (!all(required_cols %in% colnames(group1))) {
stop("El data.frame 'group1' no contiene las columnas necesarias.")
stop("The 'group1' data.frame does not contain the required columns.")
}
if (!all(required_cols %in% colnames(group2))) {
stop("El data.frame 'group2' no contiene las columnas necesarias.")
stop("The 'group2' data.frame does not contain the required columns.")
}

# Combinar los datos para realizar las comparaciones
# Combine the data to make comparisons
combined_data <- merge(
group1,
group2,
Expand All @@ -136,12 +134,12 @@ CID <- function(group1, group2, coef.col = "coef", lwr.col = "lwr.ci", upr.col =
rownames(combined_data) <- combined_data$Row.names
combined_data$Row.names <- NULL

# Verificar si hubo exclusiones debido a items ausentes en un grupo
# Check whether there were any exclusions due to missing items in a group
if (nrow(combined_data) < nrow(group1) || nrow(combined_data) < nrow(group2)) {
warning("Algunos items no tienen correspondencia entre los grupos y han sido excluidos de la comparacion.")
warning("Some items do not have a match across the groups and have been excluded from the comparison.")
}

# Calcular la diferencia de los coeficientes y los intervalos de confianza
# Calculate the difference between the coefficients and the confidence intervals
combined_data <- within(combined_data, {
Delta <- round(get(paste0(coef.col, "_1")) - get(paste0(coef.col, "_2")), 3)
lwr.ci <- round(
Expand All @@ -152,7 +150,7 @@ CID <- function(group1, group2, coef.col = "coef", lwr.col = "lwr.ci", upr.col =
(get(paste0(coef.col, "_2")) - get(paste0(lwr.col, "_2")))^2), 3)
})

# Seleccionar las columnas finales para el reporte y reiniciar nombres de filas
# Select the final columns for the report and reset the row labels
result <- combined_data[, c("Delta", "lwr.ci", "upr.ci")]
row.names(result) <- NULL

Expand Down
20 changes: 10 additions & 10 deletions R/CIDsingle.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
#'in content, it is unlikely to obtain content validity coefficients close to zero.
#'
#'@references
#'Aiken, L. R. (1980). Content validity and reliability of single items or questionnaires. Educational and. Psychological Measurement, 40, 955-959. https://doi.org/10.1177/001316448004000419
#'Aiken, L. R. (1980). Content validity and reliability of single items or questionnaires. \emph{Educational and. Psychological Measurement, 40}, 955-959. \doi{10.1177/001316448004000419}
#'
#'Aiken, L. R. (1985). Three coefficients for analyzing the reliability and validity of ratings. Educational and Psychological Measurement, 45, 131-142. https://doi.org/10.1177/0013164485451012
#'Aiken, L. R. (1985). Three coefficients for analyzing the reliability and validity of ratings. \emph{Educational and Psychological Measurement, 45}, 131-142. \doi{10.1177/0013164485451012}
#'
#'Merino-Soto, C. (2018) Confidence interval for difference between coefficients of content validity (Aiken's V): a SPSS syntax. Anales de Psicologia, 34(3), 587-590. https://doi.org/10.6018/analesps.34.3.283481.
#'
#'Merino-Soto, C. (2023). Coeficientes V de Aiken: diferencias en los juicios de validez de contenido. MHSalud, 20(1), 23-32. https://doi.org/10.15359/mhs.20-1.3
#'Merino-Soto, C. (2023). Coeficientes V de Aiken: diferencias en los juicios de validez de contenido. \emph{MHSalud, 20}(1), 23-32. \doi{10.15359/mhs.20-1.3}
#'
#'Singer, J. (2010). Construction of confidence limits about effect measures: A general approach, by G. Y. Zou and A. Donner, Statistics in Medicine 2008; 27:1693-1702.Statistics in Medicine, 29(16), 1757-1759. https://doi.org/10.1002/sim.3887
#'
Expand All @@ -61,23 +61,23 @@
#'
#'@export
CIDsingle <- function(coef1, coef2, lci1, uci1, lci2, uci2) {
# Validar que todos los argumentos sean numericos
# Verify that all arguments are numeric
if (!all(sapply(list(coef1, coef2, lci1, uci1, lci2, uci2), is.numeric))) {
stop("Todos los argumentos deben ser valores numericos.")
stop("All arguments must be numeric values.")
}

# Validar que los limites sean coherentes
if (!(lci1 <= coef1 && coef1 <= uci1)) stop("El coeficiente 1 no esta dentro de su intervalo de confianza.")
if (!(lci2 <= coef2 && coef2 <= uci2)) stop("El coeficiente 2 no esta dentro de su intervalo de confianza.")
if (!(lci1 <= coef1 && coef1 <= uci1)) stop("The coefficient 1 is not within its confidence interval.")
if (!(lci2 <= coef2 && coef2 <= uci2)) stop("The coefficient 2 is not within its confidence interval.")

# Calcular la diferencia entre los coeficientes
# Calculate the difference between the coefficients
difference <- coef1 - coef2

# Calcular el intervalo de confianza para la diferencia usando MOVER
# Calculate the confidence interval for the difference using MOVER
lower_diff <- difference - sqrt((coef1 - lci1)^2 + (uci2 - coef2)^2)
upper_diff <- difference + sqrt((uci1 - coef1)^2 + (coef2 - lci2)^2)

# Retornar los resultados
# Return the results
return(data.frame(
Difference = round(difference, 3),
lwr.ci = round(lower_diff, 3),
Expand Down
Loading
Loading