1

Considering the simple code,

df <- data.frame(x = 1:2,
                 y = 3:4,
                 z = 5:6)

How can I rename with one line columns x and z using colnames()?

I understand that colnames(df)[1:2] <- c("p", "q") would modify the first two headers, but how can I rename not-together columns?

I am aware of different commands that can do the job, just wondering if there is a colnames() solution.

zx8754
  • 52,746
  • 12
  • 114
  • 209
  • 6
    `names(df)[c(1,3)] <- c("p", "q")` or `names(df)[match(c("x", "z"), names(df))] <- c("p", "q")` – GKi Mar 14 '23 at 12:13
  • 4
    `1:2` is really just shorthand for `c(1, 2)`. And you can put whatever column numbers you want in `c()`. – Gregor Thomas Mar 14 '23 at 12:33
  • @zx8754 Yes, you are right. I have thought that there exists already an old answer to this, but didn't find it. – GKi Mar 14 '23 at 12:59
  • Does this answer your question? [Selecting non-consecutive columns in R tables](https://stackoverflow.com/questions/8174237/selecting-non-consecutive-columns-in-r-tables) – Michael Roswell Mar 14 '23 at 13:02

1 Answers1

3

Instead of 1:2, which is selecting column 1 and column 2, you could use c(1,3) for column 1 and 3. Also I would use names for a data.frame instead of colnames but colnames would also work.

names(df)[c(1,3)] <- c("p", "q")

In case the positions are not known, but the names, you can use match to get the desired columns.

names(df)[match(c("x", "z"), names(df))] <- c("p", "q")

Or a more robust version in case a match is not found.

i <- c(x = "p", z = "q")[names(df)]
j <- !is.na(i)
names(df)[j] <- i[j]

Or a variant without using intermediate steps.

names(df) <- c(x = "p", z = "q", setNames(names(df), names(df)))[names(df)]

names(df) <- (\(.) c(x = "p", z = "q", setNames(., .))[.])(names(df)) #Variant

or using transform.

names(df) <- transform(as.list(setNames(names(df), names(df))), x="p", z="q")

Have also a look at Rename multiple columns by names and Canonical tidyverse method to update some values of a vector from a look-up table.


Note: In the source of colnames<- you find the lines:

    if (is.data.frame(x)) {
        names(x) <- value
    }

So I prefer to use names instead of colnames when I have a data.frame.

GKi
  • 37,245
  • 2
  • 26
  • 48