Renaming multiple columns using a column index

Advertisements

Here is my example data.frame

df <- tibble(
    ID = 1:3,
    col_x = LETTERS[1:3],
    col_q = letters[1:3],
    col_w = 3:1
)

> df
# A tibble: 3 × 4
     ID col_x col_q col_w
  <int> <chr> <chr> <int>
1     1 A     a         3
2     2 B     b         2
3     3 C     c         1

I want to rename all columns except the ID column by appending the column index (excluding the ID column). Desired output:

     ID col_x1 col_q2 col_w3
  <int> <chr>  <chr>   <int>
1     1 A      a           3
2     2 B      b           2
3     3 C      c           1

(I will remove the original x, q, w in a subsequent step). I’ve tried:

df %>% rename_with(~paste0(.x, 1), .cols = -ID)               # Works
df %>% rename_with(~paste0(.x, col_number()), .cols = -ID)    # Does nothing
df %>% rename_with(~paste0(.x, col_number()-1), .cols = -ID)  # Error: non-numeric argument to binary operator

It has just occurred to me while writing this that col_number() comes from readr unlike row_number() which comes from dplyr – so I was expecting col_number() to behave like row_number(). Given that, how can I achieve this without having to spell out each key pair in rename, e.g. rename(col_x1 = col_x, col_q2 = col_q, col_w3 = col_w)?

EDIT:

df %>% rename_with(~paste0(.x, 1:3), .cols = -ID) achieves what I want, but the number of columns is not fixed (may be many more than 3), hence needing a dynamic solution.

>Solution :

You can do:

library(dplyr)

df |>
  rename_with(\(x) paste0(x, seq_along(x)), -ID)

# A tibble: 3 × 4
     ID col_x1 col_q2 col_w3
  <int> <chr>  <chr>   <int>
1     1 A      a           3
2     2 B      b           2
3     3 C      c           1

Leave a ReplyCancel reply