我正在寻找一种简单、简洁的使用方法,dplyr::select无需重新排列列。
考虑这个数据集:
\nlibrary(tidyverse)\nhead(msleep)\n#> # A tibble: 6 \xc3\x97 11\n#> name genus vore order conservation sleep_total sleep_rem sleep_cycle awake\n#> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>\n#> 1 Cheetah Acin\xe2\x80\xa6 carni Carn\xe2\x80\xa6 lc 12.1 NA NA 11.9\n#> 2 Owl mo\xe2\x80\xa6 Aotus omni Prim\xe2\x80\xa6 <NA> 17 1.8 NA 7 \n#> 3 Mounta\xe2\x80\xa6 Aplo\xe2\x80\xa6 herbi Rode\xe2\x80\xa6 nt 14.4 2.4 NA 9.6\n#> 4 Greate\xe2\x80\xa6 Blar\xe2\x80\xa6 omni Sori\xe2\x80\xa6 lc 14.9 2.3 0.133 9.1\n#> 5 Cow Bos herbi Arti\xe2\x80\xa6 domesticated 4 0.7 0.667 20 \n#> 6 Three-\xe2\x80\xa6 Brad\xe2\x80\xa6 herbi Pilo\xe2\x80\xa6 <NA> 14.4 2.2 0.767 9.6\n#> # \xe2\x80\xa6 with 2 more variables: brainwt <dbl>, bodywt <dbl>\nRun Code Online (Sandbox Code Playgroud)\n如果我选择vore、genus和name,则生成的数据框将按照提供列的顺序排列。
msleep %>% select(vore, genus, name)\n#> # A tibble: 83 \xc3\x97 3\n#> vore genus name \n#> <chr> <chr> <chr> \n#> 1 carni Acinonyx Cheetah \n#> 2 omni Aotus Owl monkey \n#> 3 herbi Aplodontia Mountain beaver \n#> 4 omni Blarina Greater short-tailed shrew\n#> 5 herbi Bos Cow \n#> 6 herbi Bradypus Three-toed sloth \n#> 7 carni Callorhinus Northern fur seal \n#> 8 <NA> Calomys Vesper mouse \n#> 9 carni Canis Dog \n#> 10 herbi Capreolus Roe deer \n#> # \xe2\x80\xa6 with 73 more rows\nRun Code Online (Sandbox Code Playgroud)\n相反,我想将它们保留为默认顺序:name、genus、 然后vore。
我有一个解决方案(见下文),但我不喜欢它,因为它非常冗长,而且不完全 \xe2\x80\x9ctidyverse-esque\xe2\x80\x9d。\n(我正在教授 tidyverse 课程简介,并且想要一些不会吓到初学者的东西。)
\nmsleep %>% \n select(all_of(names(msleep)[names(msleep) %in% c("vore", "genus", "name")]))\n#> # A tibble: 83 \xc3\x97 3\n#> name genus vore \n#> <chr> <chr> <chr>\n#> 1 Cheetah Acinonyx carni\n#> 2 Owl monkey Aotus omni \n#> 3 Mountain beaver Aplodontia herbi\n#> 4 Greater short-tailed shrew Blarina omni \n#> 5 Cow Bos herbi\n#> 6 Three-toed sloth Bradypus herbi\n#> 7 Northern fur seal Callorhinus carni\n#> 8 Vesper mouse Calomys <NA> \n#> 9 Dog Canis carni\n#> 10 Roe deer Capreolus herbi\n#> # \xe2\x80\xa6 with 73 more rows\nRun Code Online (Sandbox Code Playgroud)\n有这样的事吗?谢谢你!
\n对于上下文:实际上,我们有一个包含大约 400 列的数据框,我们一次从中选择 ~10-20 列进行处理。原始数据框中的列顺序是有意义的,但我们不想费力地在 select 语句中以正确的顺序列出它们。我承认这是一个非常具体的需求。
\n由reprex 包于 2021 年 12 月 22 日创建(v2.0.1)
\n小智 2
您可以使用 的强大功能eval_select()来创建一个函数来选择列并对列进行排序。
library(dplyr)
select_in_order <- function(data, ...) {
ordered_cols <- sort(tidyselect::eval_select(expr(c(...)), data))
select(data, ordered_cols)
}
Run Code Online (Sandbox Code Playgroud)
所以现在这将满足您的要求。好处是,它将是您习惯于输入语句的“全部功能” select()。
# library(ggplot2) # msleep is in ggplot2
msleep %>%
select_in_order(vore, genus, name)
# this will work as well
msleep %>%
select_in_order(starts_with("sleep"), vore, name:genus)
Run Code Online (Sandbox Code Playgroud)
编辑
作为另一种选择,只需relocate()在您的陈述后使用即可select()。这种替代方法实现了以初学者易于理解的方式保持列有序的最终目标。
msleep %>%
select(vore, genus, name) %>%
relocate(any_of(names(msleep)))
Run Code Online (Sandbox Code Playgroud)