zoowalk
zoowalk

Reputation: 2134

Transform suffix into prefix in column name

I would like to move the suffix of a column name to its beginning so that it becomes its prefix. I have many columns with changing names (except the suffix), so manually renaming is not an option.

Example:

set.seed(1)
dat <- data.frame(ID = 1:5, 
                  speed.x.alpha =     runif(5), 
                  power.x.alpha = rpois(5, 1),
                  force.x.alpha = rexp(5), 
                  speed.y.beta = runif(5), 
                  power.y.beta = rpois(5, 1),
                  force.y.beta = rexp(5))

In the end end the dataframe should have the following column names:

ID, alpha.speed.x, alpha.power.x, alpha.force.x, beta.speed.x, beta.power.x, force.power.x.

I strongly assume I need a gsub/sub expression which allows me to select the characters after the last dot, which I would then paste to the colnames, and eventually remove from the end. So far without success though...

Upvotes: 1

Views: 583

Answers (2)

akrun
akrun

Reputation: 887231

Here is one option with sub. We match one or more characters that are not a . ([^.]+) from the start (^) of the string, capture it as group ((...)- inside the braces), followed by a dot (\\. - note that . is a metacharacter which signifies for any character. So, it needs to be escaped (\\) to read it as the literal character or place it inside square brackets), followed by another set of characters that are not a dot (inside the second capture group) followed by another dot and the rest of the characters until the end of the string. In the replacement, we change the order of backreferences of capture groups to get the expected output.

names(dat) <- sub("^([^.]+)\\.([^.]+)\\.(.*)", "\\3.\\1.\\2", names(dat))
names(dat)
#[1] "ID"            "alpha.speed.x" "alpha.power.x" "alpha.force.x" 
#[5] "beta.speed.y"  "beta.power.y"  "beta.force.y" 

Upvotes: 2

lmo
lmo

Reputation: 38510

A couple of gsubs and paste0 will do the trick:

gsub("y$", "x", gsub("(^.*)\\.(.*a$)", paste0("\\2", ".", "\\1"), names(dat)))
[1] "ID"            "alpha.speed.x" "alpha.power.x" "alpha.force.x" "beta.speed.x" 
[6] "beta.power.x"  "beta.force.x"

The () in the regular expression capture the characters that match the subexpression. "\." is used to match the literal "." and the "$" anchors the expression to the end of the string. The second argument pastes together the captured sub-expressions. This result is fed to a second gsub which replaces the ending "y" with an "x" if one is found.

to rename the variables, use

names(dat) <- gsub("y$", "x", gsub("(^.*)\\.(.*a$)", paste0("\\2", ".", "\\1"), names(dat)))

Upvotes: 3

Related Questions