Reputation: 2546
I have a dataframe with these column names:
# A tibble: 1 x 5
name item2 item3 item1 item12
<lgl> <lgl> <lgl> <lgl> <lgl>
1 NA NA NA NA NA
I want the columns to be in the correct order by item number.
I tried using
problem %>% select(everything(), order(contains("item")))
But it doesn't work.
My actual data set has lots of columns, so I can't just type it out; however, each of these many columns does start with item. Also, the data set is variable in the number of columns that it may have, so I don't want to index it with specific numbers.
Thank you!
Upvotes: 0
Views: 795
Reputation: 28705
You can use gtools::mixedorder for sorting character values by their numeric components
library(gtools)
df[order(grepl('item', names(df)), order(mixedorder(names(df))))]
# or
df[mixedorder(paste0(grepl('item', names(df)), names(df)))]
# name item1 item2 item3 item12
# 1 NA NA NA NA NA
or in base R (same output)
df[order(grepl('item', names(df)), as.numeric(gsub('[^1-9]', '', names(df))))]
Data used:
df <- matrix(NA, 1, 5)
colnames(df) <- c('name', paste0('item', c(2, 3, 1, 12)))
df <- as.data.frame(df)
Upvotes: 1
Reputation: 73612
You may use regexpr
.
d <- cbind(d[1], d[-1][order(as.numeric(regmatches(names(d)[-1],
regexpr("\\d+", names(d)[-1]))))])
d
# name item1 item2 item3 item12
# 1 NA NA NA NA NA
d <- structure(list(name = NA, item2 = NA, item3 = NA, item1 = NA,
item12 = NA), row.names = c(NA, -1L), class = "data.frame")
Upvotes: 1
Reputation: 7592
Base R solution:
problem[,c(grep("item",names(problem),value=TRUE,invert=TRUE), sort(grep("item",names(problem),value=TRUE)))]
This will give you a df that starts with all the columns that do not contain "item", followed by the "item" columns sorted alphabetically. Note that if you have 10 or more cases, and the first nine are "item1" etc, then "item2" will come after "item19".
Upvotes: 0