Search code examples
rdataframedplyrtidyverserename

Renaming column names with number accounting for a non-sequential column name


I have a data like this:

library(tidyverse)
dat <- cars %>%
  t() %>%
  as_tibble()
dat <- dat %>%
  rename(dummy = V10)
dat
# A tibble: 2 × 50
     V1    V2    V3    V4    V5    V6    V7    V8    V9 dummy   V11   V12   V13
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     4     4     7     7     8     9    10    10    10    11    11    12    12
2     2    10     4    22    16    10    18    26    34    17    28    14    20
# … with 37 more variables: V14 <dbl>, V15 <dbl>, V16 <dbl>, V17 <dbl>, V18 <dbl>,
#   V19 <dbl>, V20 <dbl>, V21 <dbl>, V22 <dbl>, V23 <dbl>, V24 <dbl>, V25 <dbl>,
#   V26 <dbl>, V27 <dbl>, V28 <dbl>, V29 <dbl>, V30 <dbl>, V31 <dbl>, V32 <dbl>,
#   V33 <dbl>, V34 <dbl>, V35 <dbl>, V36 <dbl>, V37 <dbl>, V38 <dbl>, V39 <dbl>,
#   V40 <dbl>, V41 <dbl>, V42 <dbl>, V43 <dbl>, V44 <dbl>, V45 <dbl>, V46 <dbl>,
#   V47 <dbl>, V48 <dbl>, V49 <dbl>, V50 <dbl>
# ℹ Use `colnames()` to see all variable names

I want the column names to be "V8, V9, dummy, V10, V11..." How can I achieve this by manipulating column names? I'm wondering if I could dplyr::rename_with to do this, but I'm not sure how to write it.

Any help would be appriciated, thank you in advance.

Edit: I'd like to know if there's a way to do this without relying on columns numbers (e.g. dat[10:49]) for specifying columns to rename, since the actual data is much bigger and I have to do this for multiple series of items. Thank you Jon Spring for pointing this out.


Solution

  • After hours of tinkering and help from the community, I was able to get it to work using:

    res <- dat %>%
      rename_with(str_replace,
                  pattern = "\\d+", replacement = function(x)
                    (x %>%
                       str_subset("\\d+") %>%
                       as.numeric() - 1 %>%
                       return()),
                  num_range("V", 10:50))
    res %>%
      names()
    
     [1] "V1"    "V2"    "V3"    "V4"    "V5"    "V6"    "V7"    "V8"    "V9"    "dummy" "V10"   "V11"  
    [13] "V12"   "V13"   "V14"   "V15"   "V16"   "V17"   "V18"   "V19"   "V20"   "V21"   "V22"   "V23"  
    [25] "V24"   "V25"   "V26"   "V27"   "V28"   "V29"   "V30"   "V31"   "V32"   "V33"   "V34"   "V35"  
    [37] "V36"   "V37"   "V38"   "V39"   "V40"   "V41"   "V42"   "V43"   "V44"   "V45"   "V46"   "V47"  
    [49] "V48"   "V49" 
    

    Thank you very much for your help!