Modify the names of a named list in R based on a logic

100 Views Asked by At

In My_list below, I want to modify the elements' names based on the following logic:

  1. Pick the repeated word in the name (ex. beginner in "(beginner_post1 - beginner_baseline)")

  2. Pick the numeric in the NON-repeated name (ex. 1 in "post1")

  3. Modify the name to "Gain_numeric(repeated word)" (ex. Gain_1(beginner))

Is it possible to apply this logic to achieve my Desired_output below?

My_list = 
  list("(beginner_post1 - beginner_baseline)"= c(5,-2),
       "(intermediate_post1 - intermediate_baseline)"= c(6,-3),
       "(advanced_post1 - advanced_baseline)"= c(4,-1),
       "(beginner_post2 - beginner_baseline)"= c(8,-2),
       "(intermediate_post2 - intermediate_baseline)"= c(9,-3),
       "(advanced_post2 - advanced_baseline)"= c(7,-1),
       "(framework notes_posttest1 - framework notes_baseline)"=c(1,2),
       "(note-taking instruction_posttest1 - note-taking instruction_baseline)"=1
  )


Desired_output = 
  list("Gain_1(beginner)"= c(5,-2),
       "Gain_1(intermediate)"= c(6,-3),
       "Gain_1(advanced)"= c(4,-1),
       "Gain_2(beginner)"= c(8,-2),
       "Gain_2(intermediate)"= c(9,-3),
       "Gain_2(advanced)"= c(7,-1),
       "Gain_1(framework notes)" = c(1,2),
       "Gain_1(note-taking instruction)"=1
)
2

There are 2 best solutions below

2
Onyambu On BEST ANSWER
res <- setNames(My_list, sub("^.([^_]+)\\D+(\\d+).*", "Gain_\\2(\\1)", names(My_list)))

$`Gain_1(beginner)`
[1]  5 -2

$`Gain_1(intermediate)`
[1]  6 -3

$`Gain_1(advanced)`
[1]  4 -1

$`Gain_2(beginner)`
[1]  8 -2

$`Gain_2(intermediate)`
[1]  9 -3

$`Gain_2(advanced)`
[1]  7 -1

$`Gain_1(framework notes)`
[1] 1 2

$`Gain_1(note-taking instruction)`
[1] 1
0
Nick On

You can use this regex:

\(([a-z -]+)\w+?(\d+)\W+\1\w+\)

which matches:

  • \( : a (
  • ([a-z -]+) : some number of letter, space and hyphen characters, captured in group 1
  • \w+? : a minimal number of word characters
  • (\d+) : some number of digits, captured in group 2
  • \W+ : some number of non-word characters
  • \1 : repeat of what was captured in group 1
  • \w+ : some number of word characters
  • \) : a )

Regex demo on regex101

In R (thanks @thelatemail):

sub("\\(([a-z -]+)\\w+?(\\d+)\\W+\\1\\w+\\)", "Gain_\\2(\\1)", names(My_list))