2

I have a list:

l <- list(1:3, 4:6)
names(l[[1]]) <- c("A1","B1","C1")
names(l[[2]]) <- c("A2","B2","C2")
l

[[1]]  
A1 B1 C1   
 1  2  3 

[[2]]  
A2 B2 C2   
 4  5  6  

I would like to switch my list element's value and name, so the output like this:

[[1]]  
1 2 3  
A1 B2 C3  

[[2]]  
4 5 6  
A2 B2 C2  

In my real list, I have 200 + sublist and each sublist have 100+ element. Is there any efficient way can achieve this in R?

Thank you in advance.

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
achai
  • 199
  • 1
  • 7

3 Answers3

3

A base solution with lapply() and setNames().

lapply(l, function(x) setNames(names(x), x))

Or you can use enframe() with deframe() from tibble.

library(tibble)
lapply(l, function(x) deframe(enframe(x)[2:1]))

Both of them give

# [[1]]
#    1    2    3 
# "A1" "B1" "C1" 
# 
# [[2]]
#    4    5    6 
# "A2" "B2" "C2"
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
2

You can do:

lapply(l, function(x) `names<-`(names(x), x))
#> [[1]]
#>    1    2    3 
#> "A1" "B1" "C1" 
#> 
#> [[2]]
#>    4    5    6 
#> "A2" "B2" "C2" 
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • cool! Thank you! Just curious, why we need backslash here for `names<-` ? – achai Aug 19 '20 at 16:20
  • @achai the function `'names<-()'` takes the second argument and gives its names to the first argument. – Allan Cameron Aug 19 '20 at 16:23
  • Why do you use lapply? I looked at https://stackoverflow.com/questions/64931905/how-to-swap-the-names-and-values-of-a-named-vector-in-r#64931927 and tried it with your version. Both methods seem to work without lapply. – George Jan 08 '23 at 14:06
0

We can use enframe/deframe with map

library(tibble)
library(purrr)
library(dplyr)
map(l, ~ enframe(.x) %>%
            select(2:1) %>% 
            deframe)
#[[1]]
#   1    2    3 
#"A1" "B1" "C1" 

#[[2]]
#   4    5    6 
#"A2" "B2" "C2" 
akrun
  • 874,273
  • 37
  • 540
  • 662