Home > other >  pivot_wider dissolves arrange
pivot_wider dissolves arrange

Time:11-29

I try to sort each row alphabetically (in order to solve this question enter image description here

But when I use pivot_wider to pivot back the order dissolves. like here:

enter image description here

The reason for this is that names_from argument keeps the original order where it comes from -> here name

I want to know Is there a solution to keep the order after pivot_wider that was arranged by arrange before?

CodePudding user response:

We may use pmap to loop over the rows and sort with na.last = TRUE

library(purrr)
pmap_dfr(df, ~ setNames(sort(c(...), na.last =TRUE), names(df)))

-output

# A tibble: 4 × 4
  ALT_1 ALT_2 ALT_3 ALT_4
  <chr> <chr> <chr> <chr>
1 AGT   CAG   G     GAT  
2 TGA   TGC   <NA>  <NA> 
3 AGC   CGC   TGA   <NA> 
4 T     <NA>  <NA>  <NA> 

If we want to use pivot_longer/pivot_wider, instead of arrange, use sort in mutate because arrange will not break the order of the 'name' column.

library(dplyr)
library(tidyr)
df %>% 
  mutate(id = row_number()) %>% 
  pivot_longer(
    -id
  ) %>% 
  group_by(id) %>% 
  mutate(value = sort(value, na.last = TRUE)) %>% 
  ungroup %>%
  pivot_wider(
    names_from = name,
    values_from = value
  ) %>%
  select(-id)

-output

# A tibble: 4 × 4
  ALT_1 ALT_2 ALT_3 ALT_4
  <chr> <chr> <chr> <chr>
1 AGT   CAG   G     GAT  
2 TGA   TGC   <NA>  <NA> 
3 AGC   CGC   TGA   <NA> 
4 T     <NA>  <NA>  <NA> 

CodePudding user response:

You can also do something similar to the pmap approach with rowwise

df <- structure(list(ALT_1 = c("GAT", "TGC", "AGC", "T"), ALT_2 = c("CAG", 
"TGA", "CGC", NA), ALT_3 = c("G", NA, "TGA", NA), ALT_4 = c("AGT", 
NA, NA, NA)), class = "data.frame", row.names = c(NA, -4L))

library(dplyr, warn.conflicts = FALSE)

df %>%
  rowwise() %>%
  mutate(c_across(everything()) %>%
    sort(na.last = TRUE) %>%
    as.data.frame.list() %>%
    setNames(names(df)))
#> # A tibble: 4 × 4
#> # Rowwise: 
#>   ALT_1 ALT_2 ALT_3 ALT_4
#>   <chr> <chr> <chr> <chr>
#> 1 AGT   CAG   G     GAT  
#> 2 TGA   TGC   <NA>  <NA> 
#> 3 AGC   CGC   TGA   <NA> 
#> 4 T     <NA>  <NA>  <NA>

Created on 2021-11-28 by the reprex package (v2.0.1)

CodePudding user response:

Just for the fun of it, yet another one:

df %>%
  rowwise() %>%
  mutate(new = list(sort(c_across(everything())))) %>%
  ungroup() %>%
  select(new) %>%
  unnest_wider(new, names_repair = ~names(df))
  • Related