pivot_wider 溶解排列

pivot_wider dissolves arrange

我尝试按字母顺序对每一行进行排序(为了解决这个问题:

这是数据框:

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))

  ALT_1 ALT_2 ALT_3 ALT_4
1   GAT   CAG     G   AGT
2   TGC   TGA  <NA>  <NA>
3   AGC   CGC   TGA  <NA>
4     T  <NA>  <NA>  <NA>

预期输出:

  ALT_1 ALT_2 ALT_3 ALT_4
1   AGT   CAG     G   GAT
2   TGA   TGC    NA    NA
3   AGC   CGC   TGA    NA
4     T    NA    NA    NA

为了实现这一点,我使用了这段代码:

library(dplyr)
library(tidyr)
df %>% 
  mutate(id = row_number()) %>% 
  pivot_longer(
    -id
  ) %>% 
  group_by(id) %>% 
  arrange(value, .by_group = TRUE) %>% 
  pivot_wider(
    names_from = name,
    values_from = value
  )

得到这个:

     id ALT_4 ALT_2 ALT_3 ALT_1
  <int> <chr> <chr> <chr> <chr>
1     1 AGT   CAG   G     GAT  
2     2 NA    TGA   NA    TGC  
3     3 NA    CGC   TGA   AGC  
4     4 NA    NA    NA    T

我发现问题出在哪里: 如果我在 pivot_longer 之后停止并在分组后使用 arrange,一切都很好,就像这里:

但是当我使用 pivot_wider 回转时,订单就消失了。喜欢这里:

原因是 names_from 参数保留了它来自的原始顺序 -> 这里 name

我想知道 arrange之前安排的pivot_wider之后的顺序有没有办法保持?

我们可以使用 pmap 循环遍历行,并使用 sortna.last = TRUE

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

-输出

# 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> 

如果我们想使用 pivot_longer/pivot_wider 而不是 arrange,请在 mutate 中使用 sort 因为 arrange 不会破坏 'name'列。

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)

-输出

# 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> 

您还可以使用 rowwise

执行类似于 pmap 方法的操作
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>

reprex package (v2.0.1)

于 2021-11-28 创建

凑热闹,再来一个:

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