pivot_longer / unnest_longer two sets of columns?

I have a dataframe with two sets of columns v and t amongst others.

I want my output to be three rows long.

  library(tidyverse)
(df <-   
tibble(id = 1, 
       v1 = 1, v2 = 2, v3 = 3,
       t1 = "a", t2 = "b", t3 = "c"
       )
)
#> # A tibble: 1 × 7
#>      id    v1    v2    v3 t1    t2    t3   
#>   <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
#> 1     1     1     2     3 a     b     c

  ## too many rows
  df %>% 
    pivot_longer(starts_with("v"),
                 names_to = "v",
                 values_to = "v_value") %>% 
    pivot_longer(starts_with("t"),
                 names_to = "t",
                 values_to = "t_value")
#> # A tibble: 9 × 5
#>      id v     v_value t     t_value
#>   <dbl> <chr>   <dbl> <chr> <chr>  
#> 1     1 v1          1 t1    a      
#> 2     1 v1          1 t2    b      
#> 3     1 v1          1 t3    c      
#> 4     1 v2          2 t1    a      
#> 5     1 v2          2 t2    b      
#> 6     1 v2          2 t3    c      
#> 7     1 v3          3 t1    a      
#> 8     1 v3          3 t2    b      
#> 9     1 v3          3 t3    c
  
  ## unnest_longer can't handle multiple cols
df %>% 
  nest(v = c(v1, v2, v3),
       t = c(t1, t2, t3)) %>% 
  unnest_longer(c("v", "t"))
#> Error: Must extract column with a single valid subscript.
#> x Subscript `var` has size 2 but must be size 1.

Created on 2021-11-11 by the reprex package (v0.3.0)

Is there an elegant way to do this? I am unsure that the naming conventions of the sets of columns will always be the consistent, but each set should always have 3 values.

Here is one way

library(tidyverse)
(df <-   
    tibble(id = 1, 
           v1 = 1, v2 = 2, v3 = 3,
           t1 = "a", t2 = "b", t3 = "c"
    )
)

vdf <- df %>%   
  pivot_longer(starts_with("v"),
               names_to = "v",
               values_to = "v_value") %>% select(id,v,v_value) %>%
  mutate(rn=row_number())
tdf <- df %>%   
  pivot_longer(starts_with("t"),
               names_to = "t",
               values_to = "t_value") %>% select(id,t,t_value)%>%
  mutate(rn=row_number())

full_join(vdf,tdf) %>% select(-rn)
1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.