Reorder specified columns in dataframe in ascending order
I have one short question, how can I change the order of data frames for selected column names only. I would need a generic solution here because I have to use it to change the number of V columns (every time with V columns> 100)
Example:
I have data:
dkk <- structure(list(A = 2L, X = 3L, C = 4L, D = 5L, Z = 6L, V1 = 5L,
V6 = 5L, V4 = 5L, V5 = 5L, V3 = 2L, V2 = 2L), .Names = c("X",
"B", "C", "D", "Z", "V1", "V6", "V4", "V5", "V3", "V2"),
class = "data.frame", row.names = c(NA, -1L))
# X B C D Z V1 V6 V4 V5 V3 V2
2 3 4 5 6 5 5 5 5 2 2
How can I change the order of the columns with V so that they are in ascending order:
# X B C D Z V1 V2 V3 V4 V5 V6
2 3 4 5 6 5 2 2 5 5 5
Many thanks!
source to share
Here is a faster option with setcolorder
fromdata.table
library(data.table)
i1 <- grep("V\\d+", names(dkk), value = TRUE)
cbind(dkk[setdiff(names(dkk), i1)], setcolorder(dkk[i1], order(i1))[])
# A B C D Z V1 V2 V3 V4 V5 V6
#1 2 3 4 5 6 5 2 2 5 5 5
It gets a little tricky when the 'V' names are mixed with other columns, for example, let's say we change the column names to
set.seed(24)
names(dkk) <- sample(names(dkk))
dkk
# D C V6 Z V4 V1 B V2 V3 A V5
#1 2 3 4 5 6 5 5 5 5 2 2
Now you need to create a numeric index of these columns with "V" ("i2"), extract the names ("i3") and assign the order of the names and columns separately
i2 <- grep("^V\\d+", names(dkk))
i3 <- names(dkk)[i2]
names(dkk)[i2] <- sort(names(dkk)[i2])
dkk[i2] <- dkk[i2][order(i3)]
To obtain
dkk
# D C V1 Z V2 V3 B V4 V5 A V6
#1 2 3 5 5 5 5 5 6 2 2 4
Update
There was one glitch in the above solution. It doesn't sort
ingest correctly when we have column names greater than 9, ie "V10", "V11", etc. Let's assume our third column name is "V100"
colnames(dkk)[3] <- "V100"
dkk
# D C V100 Z V4 V1 B V2 V3 A V5
#1 2 3 4 5 6 5 5 5 5 2 2
i2 <- grep("^V\\d+", names(dkk))
i3 <- names(dkk)[i2]
We can parse the numeric part with help parse_number
to help order
i4 <- readr::parse_number(i3)
names(dkk)[i2] <- i3[order(i4)]
dkk[i2] <- dkk[i2][order(i4)]
dkk
# D C V1 Z V2 V3 B V4 V5 A V100
#1 2 3 5 5 5 5 5 6 2 2 4
data
dkk <- structure(list(A = 2L, B = 3L, C = 4L, D = 5L, E = 6L, V1 = 5L,
V6 = 5L, V4 = 5L, V5 = 5L, V3 = 2L, V2 = 2L), .Names = c("A",
"B", "C", "D", "Z", "V1", "V6", "V4", "V5", "V3", "V2"),
class = "data.frame", row.names = c(NA, -1L))
source to share
You can try it with by order
code names:
dkk[,order(colnames(dkk))]
A B C D E V1 V2 V3 V4 V5 V6
2 3 4 5 6 5 2 2 5 5 5
EDIT To order only columns containing "V". Note. I have included column Z in the dataset. Basically, I am the c
column names that do not need to be sorted by the "V" columns that are sorted.
dkk <- structure(list(A = 2L, B = 3L, C = 4L, D = 5L, E = 6L, V1 = 5L,
V6 = 5L, V4 = 5L, V5 = 5L, V3 = 2L, V2 = 2L), .Names = c("A",
"B", "C", "D", "Z", "V1", "V6", "V4", "V5", "V3", "V2"),
class = "data.frame", row.names = c(NA, -1L))
cols <- c(colnames(dkk)[!grepl("V",names(dkk))],
colnames(dkk)[grepl("V",names(dkk))][order(colnames(dkk)[grepl("V",names(dkk))])])
dkk[,cols]
A B C D Z V1 V2 V3 V4 V5 V6
1 2 3 4 5 6 5 2 2 5 5 5
source to share