Search code examples
rtidyverse

How to pivot_longer same columns multiple times?


Data

I tried Googling and searching SO for the answer for this, but the answers typically just state how you can separate columns into two, but not group the columns separate by specific criterion. First, here is the dput for my data called hwk:

structure(list(V1 = structure(c(4, 4, 2, 2, 2, 2, 2, 2, 4, 4, 
2, 3, 2, 3, 4, 2, 2, 2, 3, 3, 2, 3, 1, 3, 3, 3, 3, 4, 1, 2, 4, 
1, 2, 3, 2, 3, 1, 1, 2, 2, 4, 3, 2, 1, 2, 3, 3, 4, 3, 3, 2, 3, 
1, 4, 3, 2, 3, 4, 1, 3, 3, 3, 2, 2, 1, 2, 3, 4, 4, 2, 4, 3, 2, 
3, 3, 3, 3, 2, 4, 3, 3, 3, 2, 2, 3, 4, 2, 4, 4, 2, 2, 3, 3), format.spss = "F8.0"), 
    V2 = structure(c(4, 4, 3, 4, 3, 4, 3, 2, 4, 1, 3, 3, 3, 4, 
    3, 3, 2, 3, 4, 3, 1, 4, 2, 3, 4, 2, 4, 3, 3, 2, 3, 2, 3, 
    3, 4, 3, 3, 3, 3, 3, 3, 2, 4, 2, 2, 2, 4, 3, 4, 4, 2, 4, 
    2, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, 3, 3, 4, 4, 4, 4, 4, 
    3, 4, 3, 3, 3, 4, 2, 4, 3, 4, 3, 3, 2, 3, 3, 4, 3, 4, 3, 
    4, 4, 3), format.spss = "F8.0"), V3 = structure(c(4, 4, 4, 
    4, 4, 4, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4), format.spss = "F8.0"), 
    V4 = structure(c(4, 4, 3, 4, 3, 4, 2, 1, 3, 2, 3, 1, 4, 4, 
    2, 3, 2, 2, 2, 4, 1, 2, 2, 2, 3, 2, 3, 2, 2, 1, 3, 1, 1, 
    2, 4, 1, 1, 2, 3, 2, 2, 1, 1, 1, 3, 2, 4, 3, 3, 3, 3, 3, 
    3, 4, 3, 1, 4, 3, 4, 3, 2, 3, 2, 1, 4, 1, 4, 1, 2, 4, 4, 
    4, 3, 3, 3, 2, 2, 1, 4, 3, 2, 3, 2, 1, 3, 4, 1, 2, 4, 3, 
    4, 2, 2), format.spss = "F8.0"), V5 = structure(c(3, 3, 3, 
    4, 3, 4, 3, 1, 1, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 
    2, 2, 2, 4, 2, 3, 2, 3, 4, 1, 4, 2, 3, 3, 2, 2, 3, 2, 2, 
    3, 3, 2, 3, 3, 3, 2, 2, 2, 3, 2, 3, 3, 2, 2, 3, 3, 2, 3, 
    2, 2, 3, 3, 3, 2, 3, 3, 3, 4, 3, 2, 3, 3, 3, 3, 3, 3, 4, 
    3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 4, 3, 3), format.spss = "F8.0"), 
    V6 = structure(c(4, 4, 3, 4, 3, 4, 4, 1, 3, 3, 3, 3, 2, 3, 
    4, 2, 4, 3, 3, 3, 3, 4, 4, 3, 3, 3, 4, 4, 4, 3, 4, 4, 3, 
    3, 3, 4, 2, 2, 3, 3, 3, 4, 2, 4, 3, 4, 4, 4, 3, 4, 2, 4, 
    3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 1, 4, 4, 4, 4, 4, 4, 
    4, 3, 4, 4, 4, 4, 2, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 
    4, 4, 4), format.spss = "F8.0"), V7 = structure(c(4, 4, 2, 
    4, 2, 4, 4, 3, 3, 3, 2, 2, 4, 4, 3, 3, 1, 4, 3, 3, 1, 2, 
    4, 3, 4, 2, 4, 4, 3, 3, 2, 2, 3, 2, 4, 3, 3, 3, 3, 3, 3, 
    1, 4, 3, 2, 2, 4, 3, 4, 4, 2, 4, 2, 3, 4, 3, 3, 3, 4, 3, 
    4, 4, 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, 4, 4, 3, 3, 4, 3, 4, 
    3, 3, 3, 3, 2, 2, 4, 4, 4, 4, 2, 4, 4, 3), format.spss = "F8.0"), 
    V8 = structure(c(4, 4, 2, 1, 2, 1, 1, 1, 3, 3, 2, 3, 2, 3, 
    4, 2, 2, 2, 3, 3, 2, 3, 1, 3, 3, 3, 3, 4, 1, 2, 4, 1, 2, 
    3, 2, 3, 1, 1, 2, 2, 3, 1, 1, 1, 2, 3, 3, 4, 3, 3, 2, 3, 
    1, 3, 4, 2, 3, 4, 1, 3, 3, 3, 2, 2, 1, 2, 3, 4, 4, 2, 4, 
    3, 4, 4, 4, 4, 3, 2, 4, 3, 3, 3, 2, 2, 3, 4, 2, 4, 4, 2, 
    1, 3, 4), format.spss = "F8.0"), V9 = structure(c(4, 4, 4, 
    4, 4, 4, 4, 4, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 2, 3, 4, 4, 
    4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 3, 2, 4, 3, 4, 
    4, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 4, 3, 4, 3, 2, 4, 
    3, 3, 4, 4, 4, 3, 4, 4, 4, 4, 4, 3, 4, 3, 4, 3, 4, 4, 4, 
    4, 3, 4, 4, 4, 4, 4, 3, 2, 4, 4, 4, 4, 4), format.spss = "F8.0"), 
    V10 = structure(c(4, 4, 2, 4, 2, 4, 3, 2, 3, 3, 3, 2, 4, 
    4, 2, 2, 1, 3, 4, 4, 1, 4, 2, 3, 3, 2, 4, 3, 2, 3, 3, 1, 
    3, 2, 4, 3, 2, 3, 3, 3, 3, 1, 2, 4, 2, 3, 4, 4, 3, 3, 2, 
    4, 2, 4, 3, 3, 4, 3, 4, 3, 4, 4, 4, 1, 4, 3, 3, 4, 3, 4, 
    4, 3, 3, 3, 3, 3, 4, 1, 4, 3, 3, 3, 3, 2, 3, 4, 4, 2, 4, 
    2, 4, 4, 3), format.spss = "F8.0"), V11 = structure(c(3, 
    3, 1, 4, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 3, 2, 2, 2, 2, 1, 
    2, 3, 1, 2, 3, 3, 2, 1, 2, 2, 2, 3, 2, 2, 3, 2, 1, 2, 2, 
    1, 1, 4, 3, 1, 3, 2, 3, 1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 3, 
    2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 4, 2, 1, 2, 2, 3, 3, 3, 
    3, 4, 3, 2, 3, 3, 2, 2, 2, 2, 1, 3, 1, 4, 1, 3), format.spss = "F8.0"), 
    V12 = structure(c(4, 4, 3, 2, 3, 2, 3, 1, 3, 3, 3, 3, 2, 
    3, 3, 2, 4, 3, 3, 4, 4, 3, 3, 4, 4, 3, 3, 3, 4, 3, 4, 4, 
    3, 3, 3, 4, 2, 2, 3, 3, 3, 4, 2, 4, 3, 4, 4, 4, 3, 4, 2, 
    4, 3, 3, 3, 3, 4, 3, 3, 2, 2, 1, 1, 3, 1, 4, 4, 4, 4, 4, 
    4, 4, 3, 3, 2, 2, 2, 2, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 
    3, 2, 3, 4), format.spss = "F8.0")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -93L))

Solution So Far

So I want the first variables to be questions for an anxiety scale with their scores for each:

hwk2 <- hwk %>% 
  pivot_longer(cols = 1:3,
               names_to = "Anxiety Test",
               values_to = "Anxiety Score")
hwk2

Which gives me this:

# A tibble: 279 x 11
      V4    V5    V6    V7    V8    V9   V10   V11   V12 `Anxiety Test` `Anxiety Score`
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>                    <dbl>
 1     4     3     4     4     4     4     4     3     4 V1                           4
 2     4     3     4     4     4     4     4     3     4 V2                           4
 3     4     3     4     4     4     4     4     3     4 V3                           4
 4     4     3     4     4     4     4     4     3     4 V1                           4
 5     4     3     4     4     4     4     4     3     4 V2                           4
 6     4     3     4     4     4     4     4     3     4 V3                           4
 7     3     3     3     2     2     4     2     1     3 V1                           2
 8     3     3     3     2     2     4     2     1     3 V2                           3
 9     3     3     3     2     2     4     2     1     3 V3                           4
10     4     4     4     4     1     4     4     4     2 V1                           2
# ... with 269 more rows

But I want the rest to be depression, so I pivot again:

hwk3 <- hwk2 %>% 
  pivot_longer(cols = 1:9,
               names_to = "Depression Test",
               values_to = "Depression Score")
hwk3

Which now gives me this:

  `Anxiety Test` `Anxiety Score` `Depression Test` `Depression Score`
   <chr>                    <dbl> <chr>                          <dbl>
 1 V1                           4 V4                                 4
 2 V1                           4 V5                                 3
 3 V1                           4 V6                                 4
 4 V1                           4 V7                                 4
 5 V1                           4 V8                                 4
 6 V1                           4 V9                                 4
 7 V1                           4 V10                                4
 8 V1                           4 V11                                3
 9 V1                           4 V12                                4
10 V2                           4 V4                                 4
# ... with 2,501 more rows

What I Want

Well now I want to group a single column that designates the test as either an anxiety test or a depression test, and a single column for the score. So basically it would look something like this:

 Test                          Test_Type                        Score
 V1                            Anxiety                          4
 V4                            Depression                       3

If there is a less roundabout way to do this, that would be great. Equally important is a solution that doesn't change the actual values of the scores but simply groups them into the categories I mentioned above.


Solution

  • Are you looking for:

    library(tidyverse)
    hwk %>%
      rename_with(.cols = everything(),
                  .fn   = ~str_c(., c(rep('_Anxiety', 3), rep('_Depression', 9)))) %>%
      pivot_longer(cols = everything(),
                   names_to = c('Test', 'Test_Type'),
                   names_pattern = '(.*)_(.*)',
                   values_to = 'Score')
    
    # A tibble: 1,116 x 3
       Test  Test_Type  Score
       <chr> <chr>      <dbl>
     1 V1    Anxiety        4
     2 V2    Anxiety        4
     3 V3    Anxiety        4
     4 V4    Depression     4
     5 V5    Depression     3
     6 V6    Depression     4
     7 V7    Depression     4
     8 V8    Depression     4
     9 V9    Depression     4
    10 V10   Depression     4
    # ... with 1,106 more rows