The code in this appendix may be directly copied into R and executed. Electronic copies of the code in this appendix are also available at http://personality-project.org/r/measuringemotion.html . Very Simple Structure (Revelle and Rocklin, 1979) has been adapted for R and is available at http://personality-project.org/r/r.vss.html.
#еееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее
#R Control sequence to examine the effect of skew in the measurement of affect
#
#Three functions are defined with default values:
# simulate.items (nvar = 72 ,nsub = 500, circum = TRUE, avloading =.6, xbias=0, ybias = -1)
# categorical.item <-function (item)
# truncate.item <- function(item,cutpoint=0)
#
these functions are then called in a loop varying the number of subjects, the average loading, and type of structure
# output is evaluated in terms of the Very Simple Structure Criterion and chi square goodness of fit
#
#еееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее
#
#
simulate.items <- function (nvar = 72 ,nsub = 500, circum = TRUE, avloading =.6, xbias=0, ybias = -1)
#
# a function to generate items with a particular structure
#True scores of items are assumed to be bivariate normal, bipolar and to lie in a two dimensional space
#Items loadings have either a simple structure (case 1) or to be uniformly distributed around a two dimensional space (case 2)
#Free parameters to be specified are:
#nvar Number of variables
#nsub Number of subjects
#Circum Simple Structure or Circumplex structure
#avloading Average item reliability
#Amount of offset from 0 in the X and Y direction (xbias and ybias )
#
#default values are included in the function definition, other values may be specified when run
#
{ #begin function
#
trueweight<- sqrt(avloading) #<---squared weights sum to 1 => true weight is sqrt(of reliability)
errorweight <- sqrt(1-trueweight*trueweight) #squared errors and true score weights add to 1
truex <- rnorm(nsub) +xbias #generate normal true scores for x + xbias
truey <- rnorm(nsub) + ybias #generate normal true scores for y + ybias
if (circum)
{radia <- seq(0,2*pi,len=nvar+1) #make a vector of radians (the whole way around the circle) if circumplex
rad <- radia[which(radia<2*pi)] #get rid of the last one
} else rad <- rep(seq(0,3*pi/2,len=4),nvar/4) #simple structure
error<- matrix(rnorm(nsub*(nvar)),nsub) #create normal error scores
trueitem <- outer(truex, cos(rad)) + outer(truey,sin(rad)) #true score matrix for each item reflects structure in rad
item<- trueweight* trueitem + errorweight*error #observed item = true score + error score
return (item) } #the value of the function is the item matrix, ready for further analysis
#
#
# еееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее
#
# Function to convert from continous variables to discrete (-3 <-> 3 ) categorical variables
categorical.item <-function (item)
{item = round(item) #round all items to nearest integer value
item[(item<=-3)] <- -3 #items < 3 become -3
item[(item>3) ] <- 3 #items >3 become 3
return(item) } #the function returns these categorical items and quits
## Function to convert a bipolar scale into a unipolar scale (i.e., to throw away information below a cutpoint)
truncate.item <- function(item,cutpoint=0) #truncate values less than cutpoint to zero
{
item[item < cutpoint] <- 0 #item values < 0 are truncated to zero (remove to not truncate)
return(item)
}
# еееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее
# simulate multiple sample sizes and examine the effect of unipolar vs. bipolar categorical items
samplesize=c(200,400,800,3200) #examine the effect of four sample sizes
nvar=18 #examine the effect of the number of variables
#vss.none <- list() #results will be stored here
vss.18 <- list()
for (i in 1:4) #generate four data sets of varying sample size
{ items=simulate.items(nsub=samplesize[i])
catitem=categorical.item(items)
truncitem=truncate.item(catitem)
#vss.none[[i]]=list(VSS(truncitem)) #examine the VSS criterion for the unrotated solution
vss.18[[i]] <- list(VSS(truncitem,rotate="varimax")) #examine VSS for the Varimax rotated solution
}
nvar=72
#vss.none <- list() #results will be stored here
vss.72 <- list()
for (i in 1:4) #generate four data sets of varying sample size
{ items=simulate.items(nsub=samplesize[i])
catitem=categorical.item(items)
truncitem=truncate.item(catitem)
#vss.none[[i]]=list(VSS(truncitem)) #examine the VSS criterion for the unrotated solution
vss.18[[i]] <- list(VSS(truncitem,rotate="varimax")) #examine VSS for the Varimax rotated solution
}
nvar=72 #results will be stored here
vss.bipolar <- list() #compare to bipolar scales
for (i in 1:4) #generate four data sets of varying sample size
{ items=simulate.items(nsub=samplesize[i])
catitem=categorical.item(items)
#truncitem=truncate.item(catitem)
#vss.none[[i]]=list(VSS(truncitem)) #examine the VSS criterion for the unrotated solution
vss.bipolar[[i]] <- list(VSS(catitem,rotate="varimax")) #examine VSS for the Varimax rotated solution
}
#now generate multiple plots
plot.new() #set up a new plot page
par(mfrow=c(2,4)) #2 rows and 4 columns allow us to compare results
for (i in 1:4) #for the 4 sample sizes show the VSS plots
{ x=as.data.frame(vss.bipolar[[i]])
plotVSS(x,paste("N= ",samplesize[i], " 72 bipoloar variables")) }
for (i in 1:4)
{ x=as.data.frame(vss.72[[i]])
plotVSS(x,paste("N= ",samplesize[i], " 72 unipolar variables")) }
vss.72bipolar=recordPlot() #bipolar vs. unipolar VSS
plot.new() #set up a new plot page
par(mfrow=c(2,4)) #2 rows and 4 columns allow us to compare results
for (i in 1:4) #for the 4 sample sizes show the VSS plots
{ x=as.data.frame(vss.18[[i]])
plotVSS(x,paste("N= ",samplesize[i], " 18 unipoloar variables")) }
for (i in 1:4)
{ x=as.data.frame(vss.72[[i]])
plotVSS(x,paste("N= ",samplesize[i], " 72 unipolar variables")) }
vss.18v72 = recordPlot() #18 variable vs. 72 variable
The top four panels in Figure Appendix 1 shows the Very Simple Structure criterion applied for four sample sizes (N=200,400,800, and 3,200) to 72 bipolar items in a circumplex structure. The bottom four panels display the VSS criterion for 72 unipolar items also in a circumplex structure. Two things to note: as expected given that the bipolar data were generated to fit the circumplex, they do, and a two dimensional fits very well. In terms of conventional goodness of fit measures, the unipolar data require more than two dimensions, but the VSS criterion clearly indicates that a 2 dimensional solution is most interpretable if every item is thought to load on only one or at most two factors.
Figure 2 shows the Very Simple Structure criterion applied to four sample sizes (N = 200, 400 800, 3,200) for 18 versus 72 uni-polar variables in a circumplex structure.