Search code examples
rdataframerows

How to transfer a set of rows to the end of the first row with conditional in a data frame


I need to have all the rows of each participant in a single row because I want to run a repeated measures Anova.

The data frame I have now:

eyetracking <- data.frame(
  participant = c("s001","s001","s001","s002","s002","s002","s003","s003","s003"),
  trial = c(1,2,3,1,2,3,1,2,3),
  picture = c("A","C","B","C","A","B","B","A","C"),
  response_time = c("2315","2513","2145","1902","2562","2723","2465","2317","2156"))

participant trial picture response_time
       s001     1       A          2315  
       s001     2       C          2513 
       s001     3       B          2145 
       s002     1       C          1902
       s002     2       A          2562 
       s002     3       B          2723 
       s003     1       B          2465 
       s003     2       A          2317 
       s003     3       C          2156 

What I need to look like

participant trial_1 picture_1 response_time_1 trial_2 picture_2 response_time_2  trial_3 picture_3 response_time_3
       s001     1       A          2315             2         C            2513        3         B            2145   
       s002     1       C          1902             2         A            2562        3         B            2723
       s003     1       B          2465             2         A            2317        3         C            2156

What I tried to do, but failed because then I would have to write this code manually for every 122 participants and join them all again:

s001a <- data.frame(eyetracking[1,])
s001b <- data.frame(eyetracking[2,])
s001c <- data.frame(eyetracking[3,])

colnames(s001a) <- paste(colnames(s001a),"1",sep="_")
colnames(s001a)[1] <- "participant"
colnames(s001b) <- paste(colnames(s001b),"2",sep="_")
colnames(s001b)[1] <- "participant"
colnames(s001c) <- paste(colnames(s001c),"3",sep="_")
colnames(s001c)[1] <- "participant"

library(plyr)
s001all <- join_all(list(s001a,s001b,s001c), by='participant', type='left')

Solution

  • Here's a quick approach:

    library(tidyr)
    pivot_wider(eyetracking,
                names_from = trial,
                values_from = 3:4)
    # A tibble: 3 × 7
      participant picture_1 picture_2 picture_3 response_time_1 response_time_2 response_time_3
      <chr>       <chr>     <chr>     <chr>     <chr>           <chr>           <chr>          
    1 s001        A         C         B         2315            2513            2145           
    2 s002        C         A         B         1902            2562            2723           
    3 s003        B         A         C         2465            2317            2156 
    

    I've taken the liberty here to remove the (now obsolete) columns starting with trial. If you want to keep them, just replace values_from = 3:4 by values_from = 2:4.