This version of the code sets up a sub-experiment where every participant makes association between all affect tokens (Happy vs Sad; Excited vs Bored; Stressed vs Calm; Pleased vs Disgusted) and each of the other domains (Pitch, Amplitude, Noise, Shape, Size, Color, Brightness, Speed).
Each participant is given each Affect pair once as an inducer, and once as a concurrent for all of the other domains, for a total of 64 trials.
First, we will load in the packages we need
library(tidyr) # for unite()
library(magrittr) # for pipe (%>%)
library(plyr)
Then, we will specify what all of the tokens are for each of the domains that we are interested in. This creates a list of lists (roughly, a dictionary)
Tokens <- list(Pitch = c("Hum", "Piano", "Pulse", "Tone"),
Amp = c("Hum", "Piano", "Pulse", "Tone"),
Noise = c("Hum", "Piano", "Pulse", "Tone"),
Shape = c("BK1", "BK2", "BK3", "BK4"),
Size = c("Circles", "Squares", "Triangles", "Diamonds"),
Brightness = c("Circles", "Squares", "Triangles", "Diamonds"),
Color = c("RG", "RY", "YB", "RB"),
Speed = c("SP1", "SP2", "SP3", "SP4"))
Domains <- names(Tokens)
Now we can stick this all together, which we will do with a function. We do this as a function so that we can then call that function multiple times and output multiple stimulus list files.
First we create all of the relevant combinations that we want to test, with each token for Affect as both an Inducer and as a Concurrent with all other domains
Second, we assign tokens for our non-focal domains
Third, we randomize the possible configurations of trials for where the “High” inducer and concurrent go
Fourth, we assign the stimuli to their locations based on their trial type
Fifth, we shuffle the stimlist and add trial numbers
createstimuli <- function() {
AffectTokens <- c("EB", "HS", "PD", "SC")
Inducers <- expand.grid(Inducer = AffectTokens, Concurrent = Domains) #1 - Create relevant combinations
Concurrents <- expand.grid(Inducer = Domains, Concurrent = AffectTokens)
Inducers <- Inducers[order(Inducers$Concurrent),]
Concurrents <- Concurrents[order(Concurrents$Inducer),]
NonFocalTokens <-c(sapply(Domains, function(d) sample(Tokens[[d]], 1))) #2 Assign tokens for non-focal domains
Inducers$ConcurrentToken <- rep(NonFocalTokens, each=4)
Concurrents$InducerToken <- rep(NonFocalTokens, each=4)
Inducers$InducerToken <- Inducers$Inducer
Concurrents$ConcurrentToken <- Concurrents$Concurrent
Inducers$Inducer <- "Affect"
Concurrents$Concurrent <- "Affect"
TrialList <- rbind(Inducers, Concurrents) #Randomize trial type
TrialList$TrialType <- rep(sample(1:4),16)
TrialList$Focal1 <- "Affect"
TrialList$InducerL <- mapvalues(TrialList$TrialType,
from = c(1, 2, 3, 4),
to = c("H", "H", "L", "L"))
TrialList$InducerR <- mapvalues(TrialList$TrialType,
from = c(1, 2, 3, 4),
to = c("L", "L", "H", "H")) #4 Assign locations for all stims
TrialList$ConcurrentL <- mapvalues(TrialList$TrialType,
from = c(1, 2, 3, 4),
to = c("H", "L", "H", "L"))
TrialList$ConcurrentR <- mapvalues(TrialList$TrialType,
from = c(1, 2, 3, 4),
to = c("L", "H", "L", "H"))
TrialList$InducerL <- with(TrialList, paste(Inducer, InducerToken, InducerL, sep = '-'))
TrialList$InducerR <- with(TrialList, paste(Inducer, InducerToken, InducerR, sep = '-'))
TrialList$ConcurrentL <- with(TrialList, paste(Concurrent, ConcurrentToken, ConcurrentL, sep = '-'))
TrialList$ConcurrentR <- with(TrialList, paste(Concurrent, ConcurrentToken, ConcurrentR, sep = '-'))
TrialList <- TrialList[sample(nrow(TrialList)), ] #5 Shuffle the order of trials
TrialList$TrialNum <- seq(nrow(TrialList))
TrialList <- subset(TrialList, select=c("TrialNum", "Focal1", "Inducer", "Concurrent", "TrialType",
"InducerL", "InducerR", "ConcurrentL", "ConcurrentR"))
########################
# Finally just a bit of cleanup
return(TrialList)
}
So that’s our CreateStimuli function, which outputs us a stimlist as a data frame.
All we need to do is save this data frame as a CSV (which can then be read by our jsPsych code), and of course to do that multiple times- we need to generate a large number of stimlists - one for each participant in this version of the experiment
To do that, we’ll write another function, and inside of that function we will call the CreateStimuli function a number of times
writestimuli <- function(n, conditionname= "Affect") {
# do n times, storing the current iteration number in 'i'
for (i in 1:n) {
# create stimuli data frame. 'dimensions' is already in the right format so
# just pass it on directly
stimuli <- createstimuli()
# add participant 'Id' column (concatenation of the conditionname and 'i')
stimuli <- cbind(Id=paste(conditionname, i, sep="-"), stimuli)
# write resulting data frame to a file
write.table(stimuli,
paste("D:/GitHub Repos/Crossmodality-Toolkit/Stimuli/Stimlists/Affect/", "Stimuli-", conditionname, "-", i, ".csv", sep=""),
sep = "\t", row.names=FALSE)
}
}
Then finally, we just need to call our writestimuli a number of times, once for each stimlist that we want- in this case we are going to be running 60 participants, but lets generate 100 stimlists, just to be on the safe side.
writestimuli(100)