diff --git a/DESCRIPTION b/DESCRIPTION index 1e94676..fd2a1f3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: latent2likert Title: Converting Latent Variables into Likert Scale Responses -Version: 1.2.1 +Version: 1.2.2 Authors@R: person("Marko", "Lalovic", , "marko@lalovic.io", role = c("aut", "cre")) Description: Effectively simulates the discretization process inherent to @@ -11,17 +11,17 @@ Description: Effectively simulates the discretization process inherent to survey data that use Likert scales, especially when applying statistical techniques that require metric data. License: MIT + file LICENSE -URL: https://lalovic.io/latent2likert/ +URL: https://latent2likert.lalovic.io/ BugReports: https://github.com/markolalovic/latent2likert/issues/ Depends: R (>= 3.5) Imports: graphics, mvtnorm, - sn, stats, utils Suggests: + sn, knitr, rmarkdown, testthat (>= 3.0.0) diff --git a/NAMESPACE b/NAMESPACE index 963330a..5800866 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export(discretize_density) +export(estimate_mean_and_sd) export(estimate_params) export(plot_likert_transform) export(response_prop) diff --git a/NEWS.md b/NEWS.md index 3776035..a77c553 100644 --- a/NEWS.md +++ b/NEWS.md @@ -28,3 +28,9 @@ - Modularized core functions for improved readability. - Improved the structure and organization of the codebase. - Enhanced error handling for various correlation input scenarios. + +## Version 1.2.2 +- Release date: 2024-07-26 +- Exported previously internal function `estimate_mean_and_sd` based on user feedback, now available for direct use. +- Moved the package `sn` to Suggests. +- Fixed vignette building errors. diff --git a/R/estimation.R b/R/estimation.R index 74ca600..31216eb 100644 --- a/R/estimation.R +++ b/R/estimation.R @@ -98,7 +98,7 @@ estimate_params <- function(data, n_levels, skew = 0) { #' responses. The algorithm ensures stability by reparameterizing the system #' and applying constraints to prevent stepping into invalid regions. #' -#' @noRd +#' @export estimate_mean_and_sd <- function(prob, n_levels, skew = 0, eps = 1e-6, maxit = 100) { prob <- as.vector(pad_levels(prob, n_levels)) diff --git a/README.Rmd b/README.Rmd index c6151df..2778ce9 100644 --- a/README.Rmd +++ b/README.Rmd @@ -28,12 +28,17 @@ The **latent2likert** package is designed to effectively simulate the discretiza ## Installation -You can install the latest version from CRAN: +You can install the released version from CRAN: ```{r, eval = FALSE} install.packages("latent2likert") ``` +Or the latest development version from GitHub: +``` r +devtools::install_github("markolalovic/latent2likert") +``` + ## Dependencies To keep the package lightweight, **latent2likert** only imports [mvtnorm](https://cran.r-project.org/package=mvtnorm), along with the standard R packages stats and graphics, which are typically included in R releases. An additional suggested dependency is the package [sn](https://cran.r-project.org/package=sn), which is required only for generating random responses from correlated Likert items based on a multivariate skew normal distribution. The package prompts the user to install this dependency during interactive sessions if needed. diff --git a/README.html b/README.html index 711c733..68b5eb5 100644 --- a/README.html +++ b/README.html @@ -607,28 +607,7 @@

latent2likert Package logo

-

R-CMD-check - - - - - - - - - - - - - - codecov - codecov - 98% - 98% - - - - CRAN status

+

R-CMD-check codecov CRAN status

Overview

@@ -640,8 +619,10 @@

Overview

that use Likert scales, especially when applying statistical techniques that require metric data.

Installation

-

You can install the latest version from CRAN:

+

You can install the released version from CRAN:

install.packages("latent2likert")
+

Or the latest development version from GitHub:

+
devtools::install_github("markolalovic/latent2likert")

Dependencies

To keep the package lightweight, latent2likert only imports mvtnorm, along @@ -662,10 +643,13 @@

Features

Structure

+ Overview of inputs and outputs
-Overview of inputs and outputs. + +

Overview of inputs and outputs.

+

Using rlikert

@@ -673,70 +657,73 @@

Using rlikert

responses.

To generate a sample of random responses to one item on a 5-point Likert scale, use:

-
library(latent2likert)
-rlikert(size = 10, n_items = 1, n_levels = 5)
-#>  [1] 2 5 2 2 3 2 4 4 3 3
+
library(latent2likert)
+rlikert(size = 10, n_items = 1, n_levels = 5)
+#>  [1] 4 4 2 3 5 2 4 2 3 3

To generate responses to multiple items with specified parameters:

-
rlikert(size = 10,
-        n_items = 3,
-        n_levels = c(4, 5, 6),
-        mean = c(0, -1, 0), 
-        sd   = c(0.8, 1, 1),
-        corr = 0.5)
-#>       Y1 Y2 Y3
-#>  [1,]  3  4  3
-#>  [2,]  1  2  1
-#>  [3,]  3  1  3
-#>  [4,]  2  1  3
-#>  [5,]  2  1  4
-#>  [6,]  2  2  5
-#>  [7,]  3  2  5
-#>  [8,]  1  1  2
-#>  [9,]  3  2  3
-#> [10,]  2  2  3
+
rlikert(size = 10,
+        n_items = 3,
+        n_levels = c(4, 5, 6),
+        mean = c(0, -1, 0), 
+        sd   = c(0.8, 1, 1),
+        corr = 0.5)
+#>       Y1 Y2 Y3
+#>  [1,]  3  2  4
+#>  [2,]  2  1  1
+#>  [3,]  2  1  2
+#>  [4,]  3  2  4
+#>  [5,]  2  2  4
+#>  [6,]  2  3  5
+#>  [7,]  3  1  2
+#>  [8,]  2  2  3
+#>  [9,]  2  3  5
+#> [10,]  3  2  5

You can also provide a correlation matrix:

-
corr <- matrix(c(1.00, -0.63, -0.39, 
-                 -0.63, 1.00, 0.41, 
-                 -0.39, 0.41, 1.00), nrow=3)
-data <- rlikert(size = 10^3,
-                n_items = 3,
-                n_levels = c(4, 5, 6),
-                mean = c(0, -1, 0), 
-                sd   = c(0.8, 1, 1),
-                corr = corr)
+
corr <- matrix(c(1.00, -0.63, -0.39, 
+                 -0.63, 1.00, 0.41, 
+                 -0.39, 0.41, 1.00), nrow=3)
+data <- rlikert(size = 10^3,
+                n_items = 3,
+                n_levels = c(4, 5, 6),
+                mean = c(0, -1, 0), 
+                sd   = c(0.8, 1, 1),
+                corr = corr)

Note that the correlations among the Likert response variables are only estimates of the actual correlations between the latent variables, and these estimates are typically lower:

-
cor(data)
-#>            Y1         Y2         Y3
-#> Y1  1.0000000 -0.5384098 -0.3715239
-#> Y2 -0.5384098  1.0000000  0.4012943
-#> Y3 -0.3715239  0.4012943  1.0000000
+
cor(data)
+#>            Y1         Y2         Y3
+#> Y1  1.0000000 -0.5223151 -0.3449648
+#> Y2 -0.5223151  1.0000000  0.3398699
+#> Y3 -0.3449648  0.3398699  1.0000000

Using estimate_params

Given the data, you can estimate the values of latent parameters using:

-
estimate_params(data, n_levels = c(4, 5, 6), skew = 0)
-#>          items
-#> estimates          Y1          Y2          Y3
-#>      mean -0.06292803 -0.98863044  0.10704210
-#>      sd    0.81566374  1.08402520  0.95083534
+
estimate_params(data, n_levels = c(4, 5, 6), skew = 0)
+#>          items
+#> estimates           Y1           Y2           Y3
+#>      mean  0.006261483 -0.952847125 -0.011843866
+#>      sd    0.745185144  1.012219189  0.954714824

Transformation

To visualize the transformation, you can use plot_likert_transform(). It plots the densities of latent variables in the first row and transformed discrete probability distributions below:

-
plot_likert_transform(n_items = 3,
-                      n_levels = 5,
-                      mean = c(0,  -1, 0), 
-                      sd   = c(0.8, 1, 1), 
-                      skew = c(0,   0, 0.5))
+
plot_likert_transform(n_items = 3,
+                      n_levels = 5,
+                      mean = c(0,  -1, 0), 
+                      sd   = c(0.8, 1, 1), 
+                      skew = c(0,   0, 0.5))
+ Transformation of latent variables to Likert response variables
-Transformation of latent variables to Likert response -variables. + +

Transformation of latent variables to Likert response +variables.

+

diff --git a/README.md b/README.md index cd0fe8c..86a77a0 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,18 @@ metric data. ## Installation -You can install the latest version from CRAN: +You can install the released version from CRAN: ``` r install.packages("latent2likert") ``` +Or the latest development version from GitHub: + +``` r +devtools::install_github("markolalovic/latent2likert") +``` + ## Dependencies To keep the package lightweight, **latent2likert** only imports @@ -51,10 +57,13 @@ install this dependency during interactive sessions if needed. ## Structure
+ Overview of inputs and outputs
+ Overview of inputs and outputs.
+
## Using `rlikert` @@ -67,7 +76,7 @@ scale, use: ``` r library(latent2likert) rlikert(size = 10, n_items = 1, n_levels = 5) -#> [1] 2 5 2 2 3 2 4 4 3 3 +#> [1] 4 4 2 3 5 2 4 2 3 3 ``` To generate responses to multiple items with specified parameters: @@ -80,16 +89,16 @@ rlikert(size = 10, sd = c(0.8, 1, 1), corr = 0.5) #> Y1 Y2 Y3 -#> [1,] 3 4 3 -#> [2,] 1 2 1 -#> [3,] 3 1 3 -#> [4,] 2 1 3 -#> [5,] 2 1 4 -#> [6,] 2 2 5 -#> [7,] 3 2 5 -#> [8,] 1 1 2 -#> [9,] 3 2 3 -#> [10,] 2 2 3 +#> [1,] 3 2 4 +#> [2,] 2 1 1 +#> [3,] 2 1 2 +#> [4,] 3 2 4 +#> [5,] 2 2 4 +#> [6,] 2 3 5 +#> [7,] 3 1 2 +#> [8,] 2 2 3 +#> [9,] 2 3 5 +#> [10,] 3 2 5 ``` You can also provide a correlation matrix: @@ -113,9 +122,9 @@ these estimates are typically lower: ``` r cor(data) #> Y1 Y2 Y3 -#> Y1 1.0000000 -0.5384098 -0.3715239 -#> Y2 -0.5384098 1.0000000 0.4012943 -#> Y3 -0.3715239 0.4012943 1.0000000 +#> Y1 1.0000000 -0.5223151 -0.3449648 +#> Y2 -0.5223151 1.0000000 0.3398699 +#> Y3 -0.3449648 0.3398699 1.0000000 ``` ## Using `estimate_params` @@ -125,9 +134,9 @@ Given the data, you can estimate the values of latent parameters using: ``` r estimate_params(data, n_levels = c(4, 5, 6), skew = 0) #> items -#> estimates Y1 Y2 Y3 -#> mean -0.06292803 -0.98863044 0.10704210 -#> sd 0.81566374 1.08402520 0.95083534 +#> estimates Y1 Y2 Y3 +#> mean 0.006261483 -0.952847125 -0.011843866 +#> sd 0.745185144 1.012219189 0.954714824 ``` ## Transformation @@ -145,11 +154,14 @@ plot_likert_transform(n_items = 3, ```
+ Transformation of latent variables to Likert response variables
+ Transformation of latent variables to Likert response variables.
+

diff --git a/dev/fix_site.py b/dev/fix_site.py deleted file mode 100755 index 627ed96..0000000 --- a/dev/fix_site.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- - -''' -After running pkgdown::build_site(): - -* replace "reference/figures" with "../reference/figures" in vignette -* add `/docs/.nojekyll` for githubpages - -''' - -import os -import sys -import fileinput - -def replace(str_wrong, str_right, pathfilename): - ''' Replaces all occurrences of str_wrong with str_right in pathfilename. ''' - for i, line in enumerate(fileinput.input(pathfilename, inplace=1)): - sys.stdout.write(line.replace(str_wrong, str_right)) - -if __name__ == '__main__': - replace('"reference/figures', '"../reference/figures', './docs/articles/using_latent2likert.html') - os.system("touch ./docs/.nojekyll") - print("Done.") \ No newline at end of file diff --git a/docs/404.html b/docs/404.html index 76edc04..af2de06 100644 --- a/docs/404.html +++ b/docs/404.html @@ -31,7 +31,7 @@ latent2likert - 1.2.1 + 1.2.2 + + + + + +
+
+
+ +
+

Estimates the mean and standard deviation of a latent variable given the +discrete probabilities of its observed Likert scale responses.

+
+ +
+

Usage

+
estimate_mean_and_sd(prob, n_levels, skew = 0, eps = 1e-06, maxit = 100)
+
+ +
+

Arguments

+
prob
+

vector of probabilities for each response category.

+ + +
n_levels
+

number of response categories for the Likert scale item.

+ + +
skew
+

marginal skewness of the latent variable, defaults to 0.

+ + +
eps
+

tolerance for convergence, defaults to 1e-6.

+ + +
maxit
+

maximum number of iterations, defaults to 100.

+ +
+
+

Value

+ + +

A numeric vector with two elements: the estimated mean and +standard deviation.

+
+
+

Details

+

This function uses an iterative algorithm to solve the system of non-linear +equations that describe the relationship between the continuous latent +variable and the observed discrete probability distribution of Likert scale +responses. The algorithm ensures stability by reparameterizing the system +and applying constraints to prevent stepping into invalid regions.

+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/reference/estimate_params.html b/docs/reference/estimate_params.html index 8545aa2..f08fdde 100644 --- a/docs/reference/estimate_params.html +++ b/docs/reference/estimate_params.html @@ -12,7 +12,7 @@ latent2likert - 1.2.1 + 1.2.2