J.Sabree
J.Sabree

Reputation: 2546

put columns in order by number ending in R

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

Answers (3)

IceCreamToucan
IceCreamToucan

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

jay.sf
jay.sf

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

Data

d <- structure(list(name = NA, item2 = NA, item3 = NA, item1 = NA, 
    item12 = NA), row.names = c(NA, -1L), class = "data.frame")

Upvotes: 1

iod
iod

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

Related Questions