Home > Enterprise >  pivot/reshape dataframe (keep order/identifiers intact) dplyr tidyverse
pivot/reshape dataframe (keep order/identifiers intact) dplyr tidyverse

Time:10-13

How can I reshape this data frame so every line represents one player's weight and score (r). Each player is identified with a numerical marker (player "001" , "002" etc).

I have a large dataframe with many players and scores, that needs to be reshaped like so:

rm(list = ls())
df <- data.frame(gameround= c("1_1", "1_2", "1_3"),
  r001 = c(3,5,4), r002 = c(2,3,5), r003 = c(1,2,2), weight001=c(0.7,0.8,0.7), 
                 weight002 = c(0.6,0.1,0.6), weight003=c(0.2,0.7,0.2))

#current output
#gameround r001 r002 r003 weight001 weight002 weight003  
#1_1         3    2    1       0.7       0.6       0.2
#1_2         5    3    2       0.8       0.1       0.7
#1_3         4    5    2       0.7       0.6       0.2

#desired output (it is also okay to leave the weightid and rid out if a 
#certain method can ascertain that the weight-player pairs remain intact)

#gameround weightid  weight   rid    r
#1_1        001        0.7    001    3
#1_1        002        0.6    002    2
#1_1        003        0.2    003    1
#1_2        001        0.8    001    5
#1_2        002        0.1    002    3
#1_2        003        0.7    003    2
#1_3        001        0.7    001    4
#1_3        002        0.6    002    5
#1_3        003        0.2    003    2

CodePudding user response:

Using pivot_longer -

tidyr::pivot_longer(df, 
                    cols = -gameround, 
                    names_to = c('.value', 'id'), 
                    names_pattern = '([a-z] )(\\d )')

#  gameround id        r weight
#  <chr>     <chr> <dbl>  <dbl>
#1 1_1       001       3    0.7
#2 1_1       002       2    0.6
#3 1_1       003       1    0.2
#4 1_2       001       5    0.8
#5 1_2       002       3    0.1
#6 1_2       003       2    0.7
#7 1_3       001       4    0.7
#8 1_3       002       5    0.6
#9 1_3       003       2    0.2
  • Related