通过R中的查找表重命名变量

Jon*_*nny 2 r dplyr purrr tidyverse

我有一个特定顺序的数据帧:

df <- 
  data.frame(
    foo = 1:3,
    bar = LETTERS[1:3],
    baz = rnorm(3)
  )

df

  foo bar         baz
1   1   A  0.41474174
2   2   B -0.08416768
3   3   C -0.27931232
Run Code Online (Sandbox Code Playgroud)

在另一个数据框中,我将旧的变量名称与一些新名称匹配,但顺序不同:

variable_match <- 
  data.frame(
    old = names(df)[c(2, 3, 1)], 
    new = LETTERS[1:3]
  )

variable_match
  old new
1 bar   A
2 baz   B
3 foo   C
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何通过在第二个数据帧中查找相应的值来重命名原始数据框中的变量.我理想地寻找tidyverse解决方案.我尝试过各种变化:

library(tidyverse)

df %>% rename_at(variable_match$old, funs(variable_match$new))
Run Code Online (Sandbox Code Playgroud)

假设rename_at是正确的方法,但这不起作用.我想知道是否purrr::map_*是正确的方法,但不知道如何.非常感谢你的建议.

Gre*_*gor 6

这是一个单行base解决方案:

names(df2) = variable_match$new[match(names(df), variable_match$old)]
Run Code Online (Sandbox Code Playgroud)

它可能不是"理想的"(它不需要tidyverse工作),但它很简单,不需要加载任何额外的包,而是依赖于常见的内置函数.


如注释中所述,如果您更喜欢带有管道的嵌套语句(不是用于提高可读性和防止嵌套的管道?)上面的简单行相当于

library(purrr)
library(dplyr)
library(magrittr)
df = df %>%
    set_names(
        var_match %>%
        pull(new) %>%
        extract(
            names(df) %>% 
            match(var_match$old)
        )
    )
Run Code Online (Sandbox Code Playgroud)

我是管道的狂热爱好者dplyr- 当事情变得更简单,更易读时,我会一直使用它们.在这种情况下,他们采用简单的方法将其转换为编程难题,包括如何编写它以及如何阅读它.

整体上更好的界面是data.table::setnames功能.如果转换为数据表,则代码为setnames(df, old = var_match$old, new = var_match$new).如果并非所有名称都被更改,这是强大的(请参阅下面的评论).