pivot_wider 解散排列
Posted
技术标签:
【中文标题】pivot_wider 解散排列【英文标题】:pivot_wider dissolves arrange 【发布时间】:2022-01-05 18:17:01 【问题描述】:我尝试按字母顺序对每一行进行排序(为了解决这个问题Reshaping a dataframe in R by sorting just some fields in a row alphabetically:
这是数据框:
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
我想知道
有没有办法保留pivot_wider
之前由arrange
安排的订单?
【问题讨论】:
你能解释一下排序的逻辑吗?为什么第一行使用 tgc vs. tga 而不是第二行?我是否正确地假设您想要对每一行进行排序? 逻辑是按水平和字母顺序对每一行进行排序。非排序是在pivot_wider 之后的失败示例。查看预期输出。是的,对每一行进行排序。谢谢。 我很困惑,因为在您的预期输出中,第二行没有排序。 嗯,好的。谢谢德申。只要我在台式电脑上就会改变。 我冒昧地编辑了它。 【参考方案1】:我们可以使用pmap
循环遍历行,使用sort
和na.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
不会破坏“名称”列的顺序。
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>
【讨论】:
在您的解释中,您的意思是sort
不会中断...而不是arrange
?
@TarJae 我的意思是arrange
将整行排列为一个单元,而sort
分别对单个列进行排序【参考方案2】:
您也可以使用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 日创建
【讨论】:
【参考方案3】:只是为了好玩,还有一个:
df %>%
rowwise() %>%
mutate(new = list(sort(c_across(everything())))) %>%
ungroup() %>%
select(new) %>%
unnest_wider(new, names_repair = ~names(df))
【讨论】:
以上是关于pivot_wider 解散排列的主要内容,如果未能解决你的问题,请参考以下文章
R语言tidyr包pivot_longer函数pivot_wider函数数据表变换实战(长表到宽表宽表到长表)
pivot_wider 问题“`values_from` 中的值不是唯一标识的;输出将包含 list-cols”