I've searched through previous answered questions and haven't been able to construct a functioning solution yet. Here's my situation with demo data:
Say I have subjects complete a computer task where they give a response on each trial. I end up with data from each trial regarding whether they gave the accurate response and what their reaction time was:
sub1 <- data.frame(acc = round(rnorm(10, mean=.65, sd=.25), 0), RT = round(rnorm(10, mean=270, sd=30), 0))
sub2 <- data.frame(acc = round(rnorm(10, mean=.65, sd=.25), 0), RT = round(rnorm(10, mean=270, sd=30), 0))
sub3 <- data.frame(acc = round(rnorm(10, mean=.65, sd=.25), 0), RT = round(rnorm(10, mean=270, sd=30), 0))
sub.list <- list(sub1, sub2, sub3)
I've created a list where each element is a subject's data.
> sub.list
[[1]]
acc RT
1 1 259
2 0 187
3 1 256
4 1 288
5 1 304
6 1 265
7 1 312
8 1 196
9 1 335
10 0 276
[[2]]
acc RT
1 1 215
2 0 325
3 1 290
4 0 297
5 0 281
6 1 294
7 0 289
8 1 252
9 0 364
10 0 241
[[3]]
acc RT
1 0 292
2 0 267
3 0 240
4 1 321
5 1 292
6 0 269
7 1 241
8 1 206
9 1 250
10 1 283
Now comes my issue. I want to create another column for each subject that only has the RTs for accurate trials that were also preceded by an accurate response. Here's a non-working for-loop and an example of what I'm trying to end up with.
for(i in 1:length(sub.list)){
for(j in 2:nrow(sub.list[[i]])){
if(sub.list[[i]][(j-1), "acc"]==1 & sub.list[[i]][j, "acc"]==1){
sub.list[[i]][j,]$correct.RT <- sub.list[[i]][j, "RT"]
} else {
sub.list[[i]][j,]$correct.RT <- NA
}
}
}
> sub.list
[[1]]
acc RT correctRT
1 1 259 NA
2 0 187 NA
3 1 256 NA
4 1 288 288
5 1 304 304
6 1 265 265
7 1 312 312
8 1 196 196
9 1 335 335
10 0 276 NA
[[2]]
acc RT correctRT
1 1 215 NA
2 0 325 NA
3 1 290 NA
4 0 297 NA
5 0 281 NA
6 1 294 NA
7 0 289 NA
8 1 252 NA
9 0 364 NA
10 0 241 NA
[[3]]
acc RT correctRT
1 0 292 NA
2 0 267 NA
3 0 240 NA
4 1 321 NA
5 1 292 292
6 0 269 NA
7 1 241 NA
8 1 206 206
9 1 250 250
10 1 283 283
My reason for doing this is so that I can perform functions on these trials alone. For example:
> sapply(sub.list, function(x) mean(x$correctRT, na.rm=TRUE))
[1] 283.3333 NaN 257.7500
I know there must be a way to accomplish this with mapply or one of the other apply functions rather than a clumsy, slow for loop, but my hang up is how to reference sequential rows.
Any help is much appreciated!
sub.list <- lapply(sub.list, transform,
correctRT = ifelse(acc & c(0, head(acc, -1)), RT, NA))
But given your final goal, I would rather create a flag (TRUE/FALSE) variable:
sub.list <- lapply(sub.list, transform,
is.valid = acc & c(0, head(acc, -1)))
Then to compute the means for example:
sapply(sub.list, with, mean(RT[is.valid]))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With