I am building a simulator for a task that has two conditions. On each trial, the condition is supposed to go back and forth between the two levels of nCond and the respective index of the other variables. For example, trial 1 should have the stimulus "R", a pi value of .75, and a difficulty diff that is "Easy." Trial two should have the stim "L", pi of .65, and diff of "Hard", the trial three should go back to mirror trial 1 with slightly different end RTs.
What is instead happening is every trial has a condition of 2, stimulus of "L", and the same pi/mean_a/a_s/etc. I'm sure it's likely a minor issue with the second loop concerning the mycond index, but I can't quite figure out how to fix it.
Would greatly appreciate any help!
#Set a seed
set.seed(2024)
#Variable declaration-------------
nConds <- 2 #Number of conditions
stim <- c("R", "L") #Stimulus labels
pi <- c(.75, .65) #Probability of step (+1) for random walk; 1-pi will be the probability of stepping -1
diff <- c("Easy", "Hard") #Difficulty label for the condition
mean_a <- c(40, 40) #Mean upper bound for each condition
a_s <- c(0, 0) #Variability in upper bound for each condition
zp=c(.5, .5) #Multiplier of a for starting point for condition (Z = a*zp)
zp_s=c(0, 0) #Variability for starting point multiplier
Nsubs=1 #Number of subjects
Trials_per_cond=100 #Number of trials per condition
timeout=500 #Timeout parameter for the random walk
#Create an empty dataframe for storing responses
mydata=data.frame("Sub"=rep(1:1, each=100), "Trial"=1:100, "RESPONSE"=NA, "RT"=NA)
for (myperson in unique(Nsubs)){
for (mycond in 1:nConds){
condpi=pi[mycond]
cond_a=mean_a[mycond]
cond_a_s=a_s[mycond]
cond_zp=zp[mycond]
cond_zp_s=zp_s[mycond]
cond_stim=stim[mycond]
cond_diff=diff[mycond]
for (i in 1:Trials_per_cond){
mytrial=i
trial_a=rnorm(1, mean=cond_a, sd=cond_a_s)
trial_Z=rnorm(1, mean=trial_a*cond_zp, sd=cond_zp_s)
trial_Pi=rnorm(1, mean=condpi, sd=0)
#Begin setup for random walk
time=0
curpointer=trial_Z
#Conduct random walk
while (time < timeout){
time=time+1
curpointer=curpointer+sample(c(-1, 1), size=1, prob = c(1-trial_Pi, trial_Pi))
if (curpointer >= trial_a) {
myresponse="1"
break
}
else if (curpointer <= 0){
myresponse="0"
break
}
}
myRT=abs(time)
#Save the parameters to the respective trial in the dataframe
mydata[mydata$Sub==myperson & mydata$Trial==mytrial,"RESPONSE"]=myresponse
mydata[mydata$Sub==myperson & mydata$Trial==mytrial, "RT"]=myRT
mydata[mydata$Sub==myperson & mydata$Trial==mytrial, "Condition"]=mycond
mydata[mydata$Sub==myperson & mydata$Trial==mytrial, "Stimulus"]=cond_stim
}
}
}
Right now the end table looks something like this:
mydata
|sub|Trial|RESPONSE|RT |Condition|Stimulus|
|1 |1 | 1 |100 | 2 | L |
|1 |2 | 1 |130 | 2 | L |
|1 |3 | 1 |98 | 2 | L |
.....
|1 |98 | 1 |65 | 2 | L |
|1 |99 | 1 |120 | 2 | L |
|1 |100 | 1 |100 | 2 | L |
It should look like this:
mydata
|sub|Trial|RESPONSE|RT |Condition|Stimulus|
|1 |1 | 1 |102 | 1 | R |
|1 |2 | 1 |111 | 2 | L |
|1 |3 | 1 |65 | 1 | R |
.....
|1 |98 | 1 |98 | 1 | R |
|1 |99 | 1 |120 | 2 | L |
|1 |100 | 1 |100 | 1 | R |
Essentially, your innermost loop overwrites the row since both
myconditerators share sameSubandTrialconditions. Consider addingConditionas a present column in empty data frame and also in logical condition:By the way, consider a more functional form of assigning values iteratively. Since you are running elementwise across rows, use
mapplyand avoid nestedforloops:Online Demo