Banjo
Banjo

Reputation: 1251

Rename variables in a range of column names

I have some variables like below:

colnames(samp)

 [1] "Q11_1_1"  "Q11_1_2"  "Q11_1_3"  "Q11_1_4"  "Q11_1_5"  "Q11_1_6"  "Q11_1_7"  "Q11_1_8"  "Q11_1_9"  "Q11_1_10"
[11] "Q11_1_11" "Q11_1_12" "Q11_1_99" "Q11_2_1"  "Q11_2_2"  "Q11_2_3"  "Q11_2_4"  "Q11_2_5"  "Q11_2_6"  "Q11_2_7" 
[21] "Q11_2_8"  "Q11_2_9"  "Q11_2_10" "Q11_2_11" "Q11_2_12" "Q11_2_99"

I want to exchange the value in the middle and at the end e.g.

Q11_1_1 -> Q11_1_1

Q11_1_2 -> Q11_2_1

...

Q11_1_99 -> Q11_99_2

I can do it this way (but this is quite time consuming).

samp %>% 
rename(Q11_1_2 = Q11_2_1) 

Any idea how to do this?

Upvotes: 2

Views: 628

Answers (5)

G. Grothendieck
G. Grothendieck

Reputation: 269461

Here are two different alternatives. The first is more compact but the second avoids regular expressions. No packages are used in either.

1) sub Use sub like this:

# test data
DF <- data.frame("Q11_1_1" = 1, "Q11_1_2"  = 2, "Q11_1_3" = 3)

names(DF) <- sub("(\\d+)_(\\d+)$", "\\2_\\1", names(DF))

DF
##   Q11_1_1 Q11_2_1 Q11_3_1
## 1       1       2       3

2) read.table This alternative is longer but does not use any regular expressions.

# test data
DF <- data.frame("Q11_1_1" = 1, "Q11_1_2"  = 2, "Q11_1_3" = 3)

names(DF) <- with(read.table(text = names(DF), sep = "_"), paste(V1, V3, V2, sep="_"))

DF
##   Q11_1_1 Q11_2_1 Q11_3_1
## 1       1       2       3

If not all the columns are of the indicated form this will pick those that are out and just transform them. In this case we want them all so it is not needed but if there were other columns it could be used.

ix <- grep("_.*_", names(DF))  # 1:3
names(DF)[ix] <- 
with(read.table(text = names(DF)[ix], sep = "_"), paste(V1, V3, V2, sep="_"))

Upvotes: 4

BetterCallMe
BetterCallMe

Reputation: 768

Using stringr:

library(stringr)
# test data
df <- data.frame("Q11_1_1" = 1, "Q11_1_2"  = 32, "Q11_1_3" = 3, "Q11_1_99" = 
       4)
ColNames = colnames(df)
# initialise an empty vector to hold new column names
new_ColNames = vector()
for (i in 1:length(ColNames)) {
  splited = str_split(ColNames[i], "_")
  new_ColNames[i] = paste(splited[[1]][1],splited[[1]][3],splited[[1]][2], 
                          sep = "_")
}
# assign new colmun names to the df
colnames(df) = new_ColNames

Output:

> df
  Q11_1_1 Q11_2_1 Q11_3_1 Q11_99_1
1       1      32       3        4

Upvotes: 0

jay.sf
jay.sf

Reputation: 72623

You could do a split - order - paste approach.

colnames(samp) <- 
  mapply(function(x) paste(x[c(1, 3:2)], collapse="_"), strsplit(colnames(samp), "_"))

colnames(samp)
# [1] "Q11_1_1"  "Q11_1_2"  "Q11_1_3"  "Q11_1_4"  "Q11_1_5"  "Q11_1_6"  "Q11_1_7"  "Q11_1_8" 
# [9] "Q11_1_9"  "Q11_1_10" "Q11_1_11" "Q11_1_12" "Q11_1_99" "Q11_2_1"  "Q11_2_2"  "Q11_2_3" 
# [17] "Q11_2_4"  "Q11_2_5"  "Q11_2_6"  "Q11_2_7"  "Q11_2_8"  "Q11_2_9"  "Q11_2_10" "Q11_2_11"
# [25] "Q11_2_12" "Q11_2_99"

Data

samp <- structure(c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), .Dim = c(1L, 
26L), .Dimnames = list(NULL, c("Q11_1_1", "Q11_1_2", "Q11_1_3", 
"Q11_1_4", "Q11_1_5", "Q11_1_6", "Q11_1_7", "Q11_1_8", "Q11_1_9", 
"Q11_1_10", "Q11_1_11", "Q11_1_12", "Q11_1_99", "Q11_2_1", "Q11_2_2", 
"Q11_2_3", "Q11_2_4", "Q11_2_5", "Q11_2_6", "Q11_2_7", "Q11_2_8", 
"Q11_2_9", "Q11_2_10", "Q11_2_11", "Q11_2_12", "Q11_2_99")))

Upvotes: 1

fra
fra

Reputation: 852

The quickest way I can think of is a combination of strsplit and paste:

colnames(samp) <- as.vector(sapply(colnames(samp), function(x){ splitted <- unlist(strsplit(x,"_")) ; paste(splitted[1],splitted[3],splitted[2],sep="_") }))

Upvotes: -1

FAlonso
FAlonso

Reputation: 494

One of the possible solutions.

colconvert <- function(a){
    paste0(strsplit(a,"_",fixed = TRUE)[[1]][1],"_",strsplit(a,"_",fixed = TRUE)[[1]][3],"_",strsplit(a,"_",fixed = TRUE)[[1]][2])
}

names(samp) <- lapply(names(samp), colconvert)

Output:

[[1]]
[1] "Q11_1_1"

[[2]]
[1] "Q11_2_1"

[[3]]
[1] "Q11_3_1"

[[4]]
[1] "Q11_4_1"

[[5]]
[1] "Q11_5_1"

Upvotes: 2

Related Questions