vizidea
vizidea

Reputation: 193

R Converting Wide Data to Long

How can I convert my data from this:

example <- data.frame(RTD_1_LOC = c('A', 'B'), RTD_2_LOC = c('C', 'D'),
                      RTD_3_LOC = c('E', 'F'), RTD_4_LOC = c('G', 'H'),
                      RTD_5_LOC = c('I', 'J'),RTD_1_OFF = c('1', '2'), RTD_2_OFF = c('3', '4'),
                      RTD_3_OFF = c('5', '6'), RTD_4_OFF = c('7', '8'),
                      RTD_5_OFF = c('9', '10'))

to this:

example2 <- data.frame(RTD = c(1,1,2,2,3,3,4,4,5,5),LOC = c('A', 'B','C','D','E','F','G','H','I','J'),
                       OFF = c(1,2,3,4,5,6,7,8,9,10))

I have been using tidyverse gather, but I end up with about 50 columns

ex <- gather(example,RTD, Location, RTD_1_LOC:RTD_5_LOC) 
ex$RTD <- sub('_LOC',"",ex$RTD)


ex3 <- gather(ex,RTD, Offset, RTD_1_OFF:RTD_5_OFF)
ex2$RTD <- sub('_OFF',"",ex2$RTD)

Upvotes: 1

Views: 38

Answers (1)

akrun
akrun

Reputation: 887048

We can use pivot_longer from tidyr and specify the names_pattern to capture the groups from the column names. As the 'RTD' column should be left as such, specify in the names_to, a vector of 'RTD' and the column values (.value) so that the 'RTD' will get the digits capture ((\\d+) and the word ((\\w+)) 'LOC', 'OFF' will be created as new columns with the column values

library(dplyr)
library(tidyr)
 example %>% 
     pivot_longer(cols = everything(), 
      names_to = c("RTD", ".value"), names_pattern = "\\w+_(\\d+)_(\\w+)")

-output

# A tibble: 10 x 3
   RTD   LOC   OFF  
   <chr> <chr> <chr>
 1 1     A     1    
 2 2     C     3    
 3 3     E     5    
 4 4     G     7    
 5 5     I     9    
 6 1     B     2    
 7 2     D     4    
 8 3     F     6    
 9 4     H     8    
10 5     J     10   

Upvotes: 4

Related Questions