Remove elements of a named list based on the naming match in R

82 Views Asked by At

Please note: this question is completely different from a previous question.

In My_list below, I wonder how to eliminate whole elements whose names' prefix "Gain" has a different number attached to it?

For example, element #1's name is: Gain1(conventional) - Gain2(conventional), therefore, this element must be REMOVED because we have Gain1 vs. Gain2.

But element #2's name is: Gain1(conventional) - Gain1(framework notes), therefore, this element must be KEPT because we have Gain1 vs. Gain1.

Is this possible in R?

My_list <-

list(`Gain1(conventional) - Gain2(conventional)` = c(5L, -1L, 
-9L, 1L), `Gain1(conventional) - Gain1(framework notes)` = c(5L, 
-1L, -6L, 2L), `Gain1(conventional) - Gain2(framework notes)` = c(5L, 
-1L, -10L, 2L), `Gain1(conventional) - Gain1(note-taking instruction)` = c(5L, 
-1L, -7L, 3L), `Gain1(conventional) - Gain2(note-taking instruction)` = c(5L, 
-1L, -11L, 3L), `Gain1(conventional) - Gain1(vocabulary notebook)` = c(5L, 
-1L, -8L, 4L), `Gain1(conventional) - Gain2(vocabulary notebook)` = c(5L, 
-1L, -12L, 4L), `Gain2(conventional) - Gain1(framework notes)` = c(9L, 
-1L, -6L, 2L), `Gain2(conventional) - Gain2(framework notes)` = c(9L, 
-1L, -10L, 2L), `Gain2(conventional) - Gain1(note-taking instruction)` = c(9L, 
-1L, -7L, 3L), `Gain2(conventional) - Gain2(note-taking instruction)` = c(9L, 
-1L, -11L, 3L), `Gain2(conventional) - Gain1(vocabulary notebook)` = c(9L, 
-1L, -8L, 4L), `Gain2(conventional) - Gain2(vocabulary notebook)` = c(9L, 
-1L, -12L, 4L), `Gain1(framework notes) - Gain2(framework notes)` = c(6L, 
-2L, -10L, 2L), `Gain1(framework notes) - Gain1(note-taking instruction)` = c(6L, 
-2L, -7L, 3L), `Gain1(framework notes) - Gain2(note-taking instruction)` = c(6L, 
-2L, -11L, 3L), `Gain1(framework notes) - Gain1(vocabulary notebook)` = c(6L, 
-2L, -8L, 4L), `Gain1(framework notes) - Gain2(vocabulary notebook)` = c(6L, 
-2L, -12L, 4L), `Gain2(framework notes) - Gain1(note-taking instruction)` = c(10L, 
-2L, -7L, 3L), `Gain2(framework notes) - Gain2(note-taking instruction)` = c(10L, 
-2L, -11L, 3L), `Gain2(framework notes) - Gain1(vocabulary notebook)` = c(10L, 
-2L, -8L, 4L), `Gain2(framework notes) - Gain2(vocabulary notebook)` = c(10L, 
-2L, -12L, 4L), `Gain1(note-taking instruction) - Gain2(note-taking instruction)` = c(7L, 
-3L, -11L, 3L), `Gain1(note-taking instruction) - Gain1(vocabulary notebook)` = c(7L, 
-3L, -8L, 4L), `Gain1(note-taking instruction) - Gain2(vocabulary notebook)` = c(7L, 
-3L, -12L, 4L), `Gain2(note-taking instruction) - Gain1(vocabulary notebook)` = c(11L, 
-3L, -8L, 4L), `Gain2(note-taking instruction) - Gain2(vocabulary notebook)` = c(11L, 
-3L, -12L, 4L), `Gain1(vocabulary notebook) - Gain2(vocabulary notebook)` = c(8L, 
-4L, -12L, 4L))
1

There are 1 best solutions below

0
r2evans On BEST ANSWER

We can use a regex on names(My_list) and extract the Gain#.

samegain <- strcapture("Gain([0-9]+).*Gain([0-9]+)", names(My_list), list(g1=0L, g2=0L)) |>
  with(g1 == g2)
samegain
#  [1] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE
# [17]  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE
My_list[samegain]
# $`Gain1(conventional) - Gain1(framework notes)`
# [1]  5 -1 -6  2
# $`Gain1(conventional) - Gain1(note-taking instruction)`
# [1]  5 -1 -7  3
# $`Gain1(conventional) - Gain1(vocabulary notebook)`
# [1]  5 -1 -8  4
# $`Gain2(conventional) - Gain2(framework notes)`
# [1]   9  -1 -10   2
# $`Gain2(conventional) - Gain2(note-taking instruction)`
# [1]   9  -1 -11   3
# $`Gain2(conventional) - Gain2(vocabulary notebook)`
# [1]   9  -1 -12   4
# $`Gain1(framework notes) - Gain1(note-taking instruction)`
# [1]  6 -2 -7  3
# $`Gain1(framework notes) - Gain1(vocabulary notebook)`
# [1]  6 -2 -8  4
# $`Gain2(framework notes) - Gain2(note-taking instruction)`
# [1]  10  -2 -11   3
# $`Gain2(framework notes) - Gain2(vocabulary notebook)`
# [1]  10  -2 -12   4
# $`Gain1(note-taking instruction) - Gain1(vocabulary notebook)`
# [1]  7 -3 -8  4
# $`Gain2(note-taking instruction) - Gain2(vocabulary notebook)`
# [1]  11  -3 -12   4

Variants: if you have entries that is missing either Gain, then:

  1. If you need to keep them, then:

    strcapture("Gain([0-9]+).*Gain([0-9]+)", names(My_list), list(g1=0L, g2=0L)) |>
      with(is.na(g1) | is.na(g2) | g1 == g2)
    
  2. If you need to discard entries without Gain#, then:

    strcapture("Gain([0-9]+).*Gain([0-9]+)", names(My_list), list(g1=0L, g2=0L)) |>
      with(!is.na(g1) & !is.na(g2) & g1 == g2)