Home > front end >  Rename a named vector when name has a match in dataframe
Rename a named vector when name has a match in dataframe

Time:03-09

I want to replace the names in a named vector when the names have a match in a dataframe (though could be converted to a list). Here, I have a named vector called list1. Then, I have a dataframe df that has ID that would match the names in list1, and also has the new_name that I want to replace for names in list1.

Data

list1 <- c(`3381` = 0.17492310894803, `3385` = 0.114350865502778, `3389` = 0.0761515760913618, 
`3391` = 0.102018929027825, `3395` = 0.14140280849757, `3397` = 0.136809180022465
)

#      3381       3385       3389       3391       3395       3397 
#0.17492311 0.11435087 0.07615158 0.10201893 0.14140281 0.13680918 


df <- structure(list(ID = c(3389L, 3397L, 3391L, 3385L, 3381L, 3395L, 
4400L), new_name = c(163, 429, 223, 49, 3, 360, 250)), row.names = c(NA, 
-7L), class = c("tbl_df", "tbl", "data.frame"))

#     ID new_name
#  <int>    <dbl>
#1  3389      163
#2  3397      429
#3  3391      223
#4  3385       49
#5  3381        3
#6  3395      360
#7  4400      250

Expected Output

output <-c(`3` = 0.17492310894803, `49` = 0.114350865502778, `163` = 0.0761515760913618, 
          `223` = 0.102018929027825, `360` = 0.14140280849757, `429` = 0.136809180022465)

#         3         49        163        223        360        429 
#0.17492311 0.11435087 0.07615158 0.10201893 0.14140281 0.13680918 

I'm guessing that I can use Map or setNames or something, but I'm just unsure as I don't work a lot with named vectors. I searched through several posts, but could not find a comparable question.

CodePudding user response:

Simple

names(list1)=df$new_name[match(names(list1),df$ID)]

         3         49        163        223        360        429 
0.17492311 0.11435087 0.07615158 0.10201893 0.14140281 0.13680918

CodePudding user response:

We can also use enframe and deframe:

library(tidyverse)

enframe(list1) %>% 
  mutate(name = ifelse(name %in% df$ID, deframe(df)[name], name)) %>% 
  deframe

#         3         49        163        223        360        429 
#0.17492311 0.11435087 0.07615158 0.10201893 0.14140281 0.13680918 

Another option would be to left_join, then select the correct columns and again use deframe.

enframe(list1) %>%
  mutate(name = as.numeric(name)) %>%
  left_join(., df, by = c(name = "ID")) %>%
  select(new_name, value) %>%
  deframe
  • Related