是否可以通过指定将 D 移动到 B 和 C 之间来重新排序数据框中的列,以便将 ABCDE 重新排序为 ABDCE?

Is it possible to reorder columns in a data frame so that ABCDE is reordered to ABDCE by specifying to move D to between B and C?

是否可以通过指定要将列 D 从其当前位置移动到 B 和 C 之间来对数据框中的列重新排序,以便将初始顺序 ABCDE 重新排序为 ABDCE?

例如,mtcars 数据集的当前顺序如下:

mtcars <- data.frame(mtcars)
> colnames(mtcars)
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear" "carb"

我想通过 运行 代码将列 gear 移动到 disphp 之间的位置,具体要求将“齿轮”移动到 hp 之间的位置disphp。结果如下所示,在数据框中 mtcars_reordered.

> colnames(mtcars_reordered)
 [1] "mpg"  "cyl"  "disp" "gear" "hp"   "drat" "wt"   "qsec" "vs"   "am" "carb"

这样可以更轻松地重新排序数据框,而无需指定所有变量的顺序。

这可能吗?如果可以,如何实现?

尝试以下功能。
参数 swap 是重新排序前 3 列的名称。

reorder_df_cols <- function(x, swap){
  i_swap <- match(swap, names(x))
  tmp1 <- x[seq_len(i_swap[1])]
  vars <- x[rev(i_swap[-1])]
  tmp2 <- x[-c(seq_len(i_swap[1]), i_swap[-1])]
  cbind(tmp1, vars, tmp2)
}

data(mtcars, package = "datasets")

swap <- c("disp", "hp", "gear")
colnames(reorder_df_cols(mtcars, swap))
# [1] "mpg"  "cyl"  "disp" "gear" "hp"   "drat" "wt"   "qsec" "vs"  
#[10] "am"   "carb"

有一个 tidyverse 动词:relocate

library(dplyr)
mtcars %>% relocate(gear, .after=disp) %>% names()
## [1] "mpg"  "cyl"  "disp" "gear" "hp"   "drat" "wt"   "qsec" "vs"   "am"  
## [11] "carb"