Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a base R function to dynamically order data.frame columns similar to dplyr everything()?

Tags:

r

Suppose you have a data.frame, and you wish to dynamically re-order the columns using base R. The input data will always look something like this. It will always contain the id, month, and year variables, as well as a variable number of data variables (denoted as v1, v2, v3, etc.)

df1 <- data.frame(
  id = 1:5,
  v1 = LETTERS[1:5],
  v2 = rep(2,5),
  v3 = rep(10,5),
  month = c("jan", "jan", "mar", "oct", "dec"),
  year = c(1999, 2001, 1984, 1979, 2019),
  stringsAsFactors = F)

I would like to re-order the columns such that id, month, and year are always the first three columns, and then place the data variables beginning in column 4.

df2 <- data.frame(
  id = 1:5,
  month = c("jan", "jan", "mar", "oct", "dec"),
  year = c(1999, 2001, 1984, 1979, 2019),
  v1 = LETTERS[1:5],
  v2 = rep(2,5),
  v3 = rep(10,5),
  stringsAsFactors = F)

I am aware this can be done with dplyr::select along with dplyr::everything.

library(dplyr)
df2 <- df1 %>% select(id, month, year, everything())

But I would like to achieve the same output using base R.

The best I have come up with is,

keep1 <- c("id", "month", "year")
keep2 <- names(df1)[!names(df1) %in% keep1]
keep3 <- c(keep1, keep2)
df2 <- df1[, keep3]

Might there be a more elegant solution? Like, might there be a function in base R similar to dplyr::everything?

like image 952
xilliam Avatar asked Nov 06 '19 16:11

xilliam


1 Answers

You can use setdiff:

df1[, c(keep1, setdiff(names(df1), keep1))]
like image 114
Konrad Rudolph Avatar answered Oct 15 '22 11:10

Konrad Rudolph