dbartram
dbartram

Reputation: 35

Move characters from beginning of column name to end of column name

I have a dataset where column names have prefixes (corresponding to panel waves), e.g.

a_age
a_sex
a_jbstat
b_age
b_sex
b_jbstat

I would like to convert the prefixes into suffixes, so that it becomes:

age_a
sex_a
jbstat_a
age_b
sex_b
jbstat_b

I'd be grateful for suggestions on efficient ways of doing this.

Upvotes: 0

Views: 274

Answers (2)

David
David

Reputation: 10232

One way to do it, is to use a regex

x <- c(
  "a_age",
  "a_sex",
  "a_jbstat",
  "b_age",
  "b_sex",
  "b_jbstat"
)

stringr::str_replace(x, "^([a-z]+)_([a-z]+)$", "\\2_\\1")
#> [1] "age_a"    "sex_a"    "jbstat_a" "age_b"    "sex_b"    "jbstat_b"

Created on 2020-05-25 by the reprex package (v0.3.0)

Edit: Full Example

df <- data.frame(
  a_age = 1,
  a_sex = 1,
  b_age = 2,
  b_sex = 2
)
df
#>   a_age a_sex b_age b_sex
#> 1     1     1     2     2

names(df) <- stringr::str_replace(names(df), "^([a-z]+)_([a-z]+)$", "\\2_\\1")
df
#>   age_a sex_a age_b sex_b
#> 1     1     1     2     2

Created on 2020-05-26 by the reprex package (v0.3.0)

Upvotes: 1

Chris Ruehlemann
Chris Ruehlemann

Reputation: 21440

You can use sub and backreference:

sub("([a-z])_([a-z]+)", "\\2_\\1", x)
[1] "age_a"    "sex_a"    "jbstat_a" "age_b"    "sex_b"    "jbstat_b"

The backreferences \\1and \\2 recall the exact character strings in the two capturing groups ([a-z]), which is recalled by \\1, and ([a-z]+), which is recalled by \\2. To obtain the desired string change, these 'recollections' are simply reversed in the replacement argument to sub.

EDIT:

If the elements are column names, you can do this:

names(df) <- sub("([a-z])_([a-z]+)", "\\2_\\1", names(df))

Upvotes: 1

Related Questions