Select row N based on values ​​from row N-1 in the data frame list

I looked at the previous answers to the questions and have not yet been able to build a functioning solution. Here is my demo data situation:

Say that I have items that fill a computer task, where they give an answer to each test. In the end, I get data from each study regarding whether they gave an accurate answer and what is the time of their reaction:

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 created a list in which each item is a data object.

 > 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 my problem. I want to create another column for each object that has only RT for exact tests, which was also preceded by an exact answer. Here's a non- working for-loop and an example of what I'm trying to finish.

 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 this is that I can only perform functions in these trials. For instance:

 > 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 do this using mapply or one of the other functions of the application, and not a clumsy, slow cycle, but I hung up to refer to consecutive lines.

Any help is much appreciated!

+4
source share
3 answers
 sub.list <- lapply(sub.list, transform, correctRT = ifelse(acc & c(0, head(acc, -1)), RT, NA)) 

But, considering your final goal, I would prefer to create a flag variable (TRUE / FALSE):

 sub.list <- lapply(sub.list, transform, is.valid = acc & c(0, head(acc, -1))) 

Then, to calculate the means, for example:

 sapply(sub.list, with, mean(RT[is.valid])) 
+4
source

You can use the mutate function in the plyr package to achieve this.

Let me first recreate the data and set what I saw so that this example reproduces.

 set.seed(123) 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) 

Now we can apply the mutate function to each data frame in your list.

 require(plyr) lapply(sub_list, mutate, acclag = c(NA, head(acc, -1)), correctRT = ifelse((acc == 0 | acclag == 0), NA, RT)) ## [[1]] ## acc RT acclag correctRT ## 1 1 307 NA NA ## 2 1 281 1 281 ## 3 1 282 1 282 ## 4 1 273 1 273 ## 5 1 253 1 253 ## 6 1 324 1 324 ## 7 1 285 1 285 ## 8 0 211 1 NA ## 9 0 291 0 NA ## 10 1 256 0 NA ## [[2]] ## acc RT acclag correctRT ## 1 0 283 NA NA ## 2 1 261 0 NA ## 3 0 297 1 NA ## 4 0 296 0 NA ## 5 0 295 0 NA ## 6 0 291 0 NA ## 7 1 287 0 NA ## 8 1 268 1 268 ## 9 0 261 1 NA ## 10 1 259 0 NA ## [[3]] ## acc RT acclag correctRT ## 1 0 278 NA NA ## 2 1 269 0 NA ## 3 0 269 1 NA ## 4 1 311 0 NA ## 5 1 263 1 263 ## 6 0 315 1 NA ## 7 1 224 0 NA ## 8 1 288 1 288 ## 9 1 274 1 274 ## 10 1 276 1 276 
+2
source
 lapply(sub.list, function(x) { a <- x$acc # Choose elements which are true, and previous is also true: b <- a & c(0, a[-length(a)]) x$correctRT <- ifelse(b, x$RT, NA) x }) 
+2
source

Source: https://habr.com/ru/post/1484069/


All Articles