Moving columns within a data.frame() without retyping
Here is one way to do it:
> col_idx <- grep("g", names(df))
> df <- df[, c(col_idx, (1:ncol(df))[-col_idx])]
> names(df)
[1] "g" "a" "b" "c" "d" "e" "f"
I wrote this function recently called moveme
. It's designed to work on vectors, with the intent of shuffling column orders around.
Here's the function:
moveme <- function (invec, movecommand) {
movecommand <- lapply(strsplit(strsplit(movecommand, ";")[[1]],
",|\\s+"), function(x) x[x != ""])
movelist <- lapply(movecommand, function(x) {
Where <- x[which(x %in% c("before", "after", "first",
"last")):length(x)]
ToMove <- setdiff(x, Where)
list(ToMove, Where)
})
myVec <- invec
for (i in seq_along(movelist)) {
temp <- setdiff(myVec, movelist[[i]][[1]])
A <- movelist[[i]][[2]][1]
if (A %in% c("before", "after")) {
ba <- movelist[[i]][[2]][2]
if (A == "before") {
after <- match(ba, temp) - 1
}
else if (A == "after") {
after <- match(ba, temp)
}
}
else if (A == "first") {
after <- 0
}
else if (A == "last") {
after <- length(myVec)
}
myVec <- append(temp, values = movelist[[i]][[1]], after = after)
}
myVec
}
Usage is simple. Try these out:
moveme(names(df), "g first")
moveme(names(df), "g first; a last; e before c")
Of course, using it to reorder the columns in your data.frame
is straightforward:
df[moveme(names(df), "g first")]
And for data.table
s (moves by reference, no copy) :
setcolorder(dt, moveme(names(dt), "g first"))
The basic options are:
- first
- last
- before
- after
Compounded moves are separated by a semicolon.
The subset
function has a nice select
argument that gives a convenient way to select ranges of columns by name:
df <- subset(df, select=c(g,a:f))
Use select
from the dplyr package and its everything()
function to move specific columns to the start or end of a data.frame.
Move to the beginning:
library(dplyr)
df %>%
select(g, everything())
Move to the end:
df %>%
select(-a, everything())
Or without the %>%
pipe operator, those would be select(df, g, everything())
and select(df, -a, everything())
respectively.