Project Status: Active – The project has reached a stable, usable state and is being actively developed. metacran downloads total metacran downloads last month R-CMD-check

LikertMakeR LikertMakeR

(V 0.4.0 November 2024)

Synthesise and correlate Likert scale and similar rating-scale data with predefined first & second moments (mean and standard deviation)

LikertMakeR synthesises rating-scale data. Such scales are constrained by upper and lower bounds and discrete increments.

Purpose

The package is intended for

  1. “reproducing” rating-scale data for further analysis and visualisation when only summary statistics have been reported,

  2. teaching. Helping researchers and students to better understand the relationships among scale properties, sample size, number of items, etc.

  3. checking the feasibility of scale moments with given scale and correlation properties

Functions

Functions in this version of LikertMakeR are:

Rating scale properties

A Likert scale is the mean, or sum, of several ordinal rating scales. They are bipolar (usually “agree-disagree”) responses to propositions that are determined to be moderately-to-highly correlated among each other, and capturing various facets of a theoretical construct.

Rating scales are not continuous or unbounded.

For example, a 5-point Likert scale that is constructed with, say, five items (questions) will have a summed range of between 5 (all rated ‘1’) and 25 (all rated ‘5’) with all integers in between, and the mean range will be ‘1’ to ‘5’ with intervals of 1/5=0.20. A 7-point Likert scale constructed from eight items will have a summed range between 8 (all rated ‘1’) and 56 (all rated ‘7’) with all integers in between, and the mean range will be ‘1’ to ‘7’ with intervals of 1/8=0.125.

Alternative approaches to synthesising scales

Typically, a researcher will synthesise rating-scale data by sampling with a predetermined probability distribution. For example, the following code will generate a vector of values for a single Likert-scale item, with approximately the given probabilities.

      n <- 128
      sample(1:5, n, replace = TRUE,
        prob = c(0.1, 0.2, 0.4, 0.2, 0.1)
      )

This approach is good for testing Likert items but it does not help when working on complete Likert scales, or for when we want to specify means and standard deviations as they might be reported in published research.

The function lfast() allows the user to specify exact univariate statistics as they might ordinarily be reported. lcor() will take multiple scales created with lfast() and rearrange values so that the vectors are correlated.

makeCorrAlpha() generates a correlation matrix from a predefined Cronbach’s Alpha(), thus enabling the user to apply lcor() and lfast() to generate scale items with an exact Cronbach’s Alpha. makeItems() will generate synthetic rating-scale data with predefined first and second moments and a predefined correlation matrix. makeItemsScale() generate a dataframe of rating scale items from a summative scale and desired Cronbach’s Alpha. correlateScales() generates a multidimensional dataframe by combining several dataframes of rating-scale items so that their summated scales are correlated according to a predefined correlation matrix.

Install LikertMakeR

To download and install the package, run the following code from your R console.

From CRAN:

 install.packages('LikertMakeR')

The latest development version is available from the author’s GitHub repository.

 library(devtools)
 install_github("WinzarH/LikertMakeR")
 

Generate synthetic rating scales

lfast()

lfast() usage

lfast(n, mean, sd, lowerbound, upperbound, items = 1, precision = 0)
lfast arguments

lfast() Example: a five-item, seven-point Likert scale

 x <- lfast(
   n = 256, 
   mean = 4.5, 
   sd = 1.0, 
   lowerbound = 1, 
   upperbound = 7, 
   items = 5
   )

lfast() Example: a four-item, five-point Likert scale with moderate precision

 x <- lfast(
   n = 256, 
   mean = 3.25, 
   sd = 1.0, 
   lowerbound = 1, 
   upperbound = 5, 
   items = 5,
   precision = 4
   )
  

lfast() Example: an 11-point likelihood-of-purchase scale

 x <- lfast(256, 2.5, 2.5, 0, 10)
 

Correlating vectors of synthetic rating scales

lcor()

The function, lcor(), applies a simple evolutionary algorithm to rearrange the values in the columns of a data set so that they are correlated at a specified level. lcor() does not change the values - it swaps their positions in each column so that univariate statistics do not change, but their correlations with other columns do.

lcor() usage

  lcor(data, target)
lcor() arguments

lcor() Example #1

generate synthetic data

  n <- 64
 x1 <- lfast(n, 3.5, 1.00, 1, 5, 5) 
 x2 <- lfast(n, 1.5, 0.75, 1, 5, 5) 
 x3 <- lfast(n, 3.0, 1.70, 1, 5, 5) 
 x4 <- lfast(n, 2.5, 1.50, 1, 5, 5)   
 
 mydat4 <- data.frame(x1, x2, x3, x4) 
 
 head(mydat4)
 cor(mydat4) |> round(3)
 

Define a target correlation matrix

 tgt4 <- matrix(
 c(
   1.00, 0.55, 0.60, 0.75,
   0.55, 1.00, 0.25, 0.65,
   0.60, 0.25, 1.00, 0.80,
   0.75, 0.65, 0.80, 1.00
 ),
 nrow = 4
 )
 

lcor() application

 new4 <- lcor(data = mydat4, target = tgt4)
 
 cor(new4) |> round(3)

lcor() example #2

three starting columns and a different target correlation matrix
 mydat3 <- data.frame(x1, x2, x3) 

 tgt3 <- matrix(
   c(
      1.00, -0.50, -0.85,
     -0.50,  1.00,  0.60,
     -0.85,  0.60,  1.00
   ),
   nrow = 3
 )
 
Apply lcor()
 new3 <- lcor(mydat3, tgt3) 
 
 cor(new3) |> round(3)

Generate a correlation matrix from Cronbach’s Alpha

makeCorrAlpha()

makeCorrAlpha(), constructs a random correlation matrix of given dimensions and predefined Cronbach’s Alpha.

makeCorrAlpha() usage

  makeCorrAlpha(items, alpha, variance = 0.5, precision = 0)
makeCorrAlpha() arguments

NOTE

Random values generated by makeCorrAlpha() are volatile. makeCorrAlpha() may not generate a feasible (positive-definite) correlation matrix, especially when

makeCorrAlpha() will inform the user if the resulting correlation matrix is positive definite, or not.

If the returned correlation matrix is not positive-definite, because solutions are so volatile, a feasible solution still may be possible, and often is. The user is encouraged to try again, possibly several times, to find one.

makeCorrAlpha() examples

four variables, Alpha = 0.85

define parameters
items <- 4
alpha <- 0.85
variance <- 0.5  
apply makeCorrAlpha() function
cor_matrix_4 <- makeCorrAlpha(items, alpha, variance)
test output with Helper functions
alpha(cor_matrix_4)
eigenvalues(cor_matrix_4, 1)

eight variables, Alpha = 0.95, larger variance

define parameters
items <- 8
alpha <- 0.95
variance <- 1.0
apply makeCorrAlpha() function
cor_matrix_8 <- makeCorrAlpha(items, alpha, variance)
test output
alpha(cor_matrix_8)
eigenvalues(cor_matrix_8, 1)

repeated with random variation around Alpha

define parameters
precision <- 2
apply makeCorrAlpha() function
cor_matrix_8a <- makeCorrAlpha(items, alpha, variance, precision)
test output
alpha(cor_matrix_8a)
eigenvalues(cor_matrix_8a, 1)

Generate a dataframe of rating scales from a correlation matrix and predefined moments

makeItems()

makeItems() generates a dataframe of random discrete values from a scaled Beta distribution so the data replicate a rating scale, and are correlated close to a predefined correlation matrix.

makeItems() is a wrapper function for:

makeItems() usage

makeItems(n, means, sds, lowerbound, upperbound, cormatrix)

makeItems() arguments

makeItems() examples

define parameters

n <- 16
dfMeans <- c(2.5, 3.0, 3.0, 3.5)
dfSds <- c(1.0, 1.0, 1.5, 0.75)
lowerbound <- rep(1, 4)
upperbound <- rep(5, 4)

corMat <- matrix(
c(
 1.00, 0.25, 0.35, 0.40,
 0.25, 1.00, 0.70, 0.75,
 0.35, 0.70, 1.00, 0.80,
 0.40, 0.75, 0.80, 1.00
 ),
 nrow = 4, ncol = 4
)

apply function

df <- makeItems(
   n = n,
   means = dfMeans,
   sds = dfSds,
   lowerbound = lowerbound,
   upperbound = upperbound,
   cormatrix = corMat
 )

test function

print(df)

apply(df, 2, mean) |> round(3)

apply(df, 2, sd) |> round(3)

cor(df) |> round(3)

Generate a dataframe of rating-scale items from a summated rating scale

makeItemsScale()

makeItemsScale() usage

makeItemsScale(scale, lowerbound, upperbound, items, 
alpha = 0.8, variance = 0.5)

makeItemsScale() arguments

makeItemsScale() Example:

generate a summated scale
n <- 64
mean <- 3.5
sd <- 1.00
lowerbound <- 1
upperbound <- 5
items <- 4

meanScale <- lfast(
  n = n, mean = mean, sd = sd,
  lowerbound = lowerbound, upperbound = upperbound,
  items = items 
)

summatedScale <- meanScale * items

create items with makeItemsScale()

newItems_1 <- makeItemsScale(
  scale = summatedScale,
  lowerbound = lowerbound, 
  upperbound = upperbound,
  items = items
)

cor(newItems_1) |> round(2)
alpha(data = newItems_1)
eigenvalues(cor(newItems_1), 1)

makeItemsScale() with same summated values and higher alpha

newItems_2 <- makeItemsScale(
  scale = summatedScale,
  lowerbound = lowerbound, 
  upperbound = upperbound,
  items = items,
  alpha = 0.9
)

cor(newItems_2) |> round(2)
alpha(data = newItems_2)
eigenvalues(cor(newItems_2), 1)

same summated values with lower alpha that may require higher variance

newItems_3 <- makeItemsScale(
  scale = summatedScale,
  lowerbound = lowerbound, 
  upperbound = upperbound,
  items = items,
  alpha = 0.6,
  variance = 0.7
)   

cor(newItems_3) |> round(2)
alpha(data = newItems_3)
eigenvalues(cor(newItems_3), 1)

Create a multidimensional dataframe of scale items as we might see from a questionnaire

correlateScales()

correlateScales() takes several dataframes of rating-scale items and rearranges their rows so that the scales are correlated according to a predefined correlation matrix. Univariate statistics for each dataframe of rating-scale items do not change, and inter-item correlations within a dataframe do not change, but their correlations with rating-scale items in other dataframes do change.

correlateScales() usage

correlateScales(dataframes, scalecors)

correlateScales() arguments

correlateScales() example

three attitude scales, each of three items
n <- 64
lower <- 1
upper <- 5
attitude #1
cor_1 <- makeCorrAlpha(items = 3, alpha = 0.85)
means_1 <- c(2.5, 2.5, 3.0)
sds_1 <- c(0.9, 1.0, 1.0)
Att_1 <- makeItems(
  n, means_1, sds_1,
  rep(lower, 4), rep(upper, 4),
  cor_1
)
attitude #2
cor_2 <- makeCorrAlpha(items = 3, alpha = 0.80)
means_2 <- c(2.5, 3.0, 3.5)
sds_2 <- c(1.0, 1.5, 1.0)
Att_2 <- makeItems(
  n, means_2, sds_2,
  rep(lower, 5), rep(upper, 5),
  cor_2
)
attitude #3
cor_3 <- makeCorrAlpha(items = 3, alpha = 0.75)
means_3 <- c(2.5, 3.0, 3.5)
sds_3 <- c(1.0, 1.5, 1.0)

Att_3 <- makeItems(
  n, means_3, sds_3,
  rep(lower, 6), rep(upper, 6),
  cor_3
)
correlateScales parameters
target scale correlation matrix
scale_cors <- matrix(
  c(
    1.0, 0.6, 0.5,
    0.6, 1.0, 0.4, 
    0.5, 0.4, 1.0
  ),
  nrow = 3
)
initial data frames
data_frames <- list("A1" = Att_1, "A2" = Att_2, "A3" = Att_3)
apply the correlateScales() function
my_correlated_scales <- correlateScales(
  dataframes = data_frames,
  scalecors = scale_cors
)
Check the properties of our derived dataframe
data structure
str(my_correlated_scales)
inter-item correlations
cor(my_correlated_scales) |> round(2)
eigenvalues of dataframe correlations
eigenvalues(cormatrix = cor(my_correlated_scales), scree = TRUE) |> 
round(2)

Helper functions

likertMakeR() includes two additional functions that may be of help when examining parameters and output.

alpha()

alpha() accepts, as input, either a correlation matrix or a dataframe. If both are submitted, then the correlation matrix is used by default, with a message to that effect.

alpha() usage

alpha(cormatrix = NULL, data = NULL)

alpha() arguments

alpha() examples

Sample data frame
df <- data.frame(
 V1  =  c(4, 2, 4, 3, 2, 2, 2, 1),
 V2  =  c(4, 1, 3, 4, 4, 3, 2, 3),
 V3  =  c(4, 1, 3, 5, 4, 1, 4, 2),
 V4  =  c(4, 3, 4, 5, 3, 3, 3, 3)
)
example correlation matrix
corMat <- matrix(
 c(
  1.00, 0.35, 0.45, 0.70,
  0.35, 1.00, 0.60, 0.55,
  0.45, 0.60, 1.00, 0.65,
  0.70, 0.55, 0.65, 1.00
 ),
 nrow = 4, ncol = 4
)

apply function examples

alpha(cormatrix = corMat)

alpha(data = df)

alpha(NULL, df)

alpha(corMat, df)

[eigenvalues()] (#eigenvalues)

eigenvalues() calculates eigenvalues of a correlation matrix, reports on whether the matrix is positive-definite, and optionally produces a scree plot.

eigenvalues() usage

eigenvalues(cormatrix, scree = FALSE) 

eigenvalues() arguments

eigenvalues() examples

define parameters

correlationMatrix <- matrix(
 c(
  1.00, 0.25, 0.35, 0.40,
  0.25, 1.00, 0.70, 0.75,
  0.35, 0.70, 1.00, 0.80,
  0.40, 0.75, 0.80, 1.00
 ),
 nrow = 4, ncol = 4
)

apply function

evals <- eigenvalues(cormatrix = correlationMatrix)

print(evals)

evals <- eigenvalues(correlationMatrix, 1)

To cite LikertMakeR

Here’s how to cite this package:

 Winzar, H. (2022). LikertMakeR: Synthesise and correlate Likert-scale 
 and related rating-scale data with predefined first & second moments, 
 Version 0.4.0 (2024),
The Comprehensive R Archive Network (CRAN),
<https://CRAN.R-project.org/package=LikertMakeR>
    

BIB:

@software{winzar2022,
title = {LikertMakeR: Synthesise and correlate Likert-scale 
and related rating-scale data with predefined first & second moments},
author = {Hume Winzar},
abstract = {LikertMakeR synthesises Likert scale and related rating-scale data with predefined means and standard deviations, and optionally correlates these vectors to fit a predefined correlation matrix or Cronbach's Alpha.},
journal = {The Comprehensive R Archive Network (CRAN)},
month = {12},
year = {2022},
version = {0.4.0, (2024)}
url = {https://CRAN.R-project.org/package=LikertMakeR},
}