【问题标题】:Rename columns using values from separate dataframe使用来自单独数据框的值重命名列
【发布时间】:2021-12-08 15:19:27
【问题描述】:

我有一个 tibble,它的列名包含空格和特殊字符,使用起来很麻烦。我想在处理数据时将这些列名称更改为更易于使用的名称,然后在最后将它们更改回原始名称以进行显示。理想情况下,我希望能够作为管道的一部分来执行此操作,但是我还没有弄清楚如何使用 rename_with() 来执行此操作。

样本数据:

df <- tibble(oldname1 = seq(1:10),
             oldname2 = letters[seq(1:10)],
             oldname3 = LETTERS[seq(1:10)])


cols_lookup <- tibble(old_names = c("oldname4", "oldname2", "oldname1"), 
                      new_names = c("newname4", "newname2", "newname1"))

期望的输出:

> head(df_renamed)
# A tibble: 6 x 3
  newname1 newname2 oldname3
     <int> <chr>    <chr>   
1        1 a        A       
2        2 b        B       
3        3 c        C       
4        4 d        D       
5        5 e        E       
6        6 f        F 

在此工作期间,一些列被删除并重新排序,因此在将它们转换回来时,cols_lookup 表中将有条目不再在 df 中。在df 中还创建了一些新列,我希望它们的名称保持不变。

我知道已经有人问过类似的问题,但是答案要么不适用于小标题或管道(例如使用 match() 的那些),要么如果列不适用'在两个表中的顺序并不相同。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以使用rename_at。从主查找表中,filter 数据集的names 匹配的行(filtered_lookup),然后在rename_at 中使用它,我们在vars 中指定“旧名称”并替换为“新名称” '

    library(dplyr)
    filtered_lookup <- cols_lookup %>% 
         filter(old_names %in% names(df)) 
    df %>% 
      rename_at(vars(filtered_lookup$old_names), ~ filtered_lookup$new_names)
    

    或者使用rename_with,使用同样的逻辑

    df %>%
      rename_with(.fn = ~filtered_lookup$new_names, .cols = filtered_lookup$old_names)
    

    或者另一种选择是rename 从命名向量拼接 (!!!)

    library(tibble)
    df %>% 
         rename(!!! deframe(filtered_lookup[2:1]))
    

    【讨论】:

    • 谢谢!我宁愿避免制作单独的filtered_lookup 表,并将所有步骤都包含在管道中。使用您的方法的管道中的管道有效,但有点难看! df %&gt;% rename(!!! deframe((cols_lookup %&gt;% filter(old_names %in% names(df)))[2:1])) 顺便说一句,rename_at 已被 rename_with 取代
    • @stiba 要让rename 工作,它需要所有相交的列。如果有不存在的名称,它将失败
    • @stlba 你也可以使用rename_with,唯一的问题是参数颠倒了
    【解决方案2】:

    您可以将rename_ 与setnames 一起使用

    cols_lookup <- tibble(old_names = c("oldname3", "oldname2", "oldname1"), 
                          new_names = c("newname3", "newname2", "newname1"))
    df
    rename_(df, .dots=setNames(cols_lookup$old_names, cols_lookup$new_names))
    
    

    输出:

    # A tibble: 10 x 3
       newname1 newname2 newname3
          <int> <chr>    <chr>   
     1        1 a        A       
     2        2 b        B       
     3        3 c        C       
     4        4 d        D       
     5        5 e        E       
     6        6 f        F       
     7        7 g        G       
     8        8 h        H       
     9        9 i        I       
    10       10 j        J       
    

    【讨论】:

    • 这不适用于我的示例数据,我的数据中没有 oldname3/newname3。 rename_() 也已被弃用,所以我宁愿避免使用它。
    猜你喜欢
    • 2020-09-11
    • 2020-01-23
    • 1970-01-01
    • 2021-02-22
    • 2018-01-04
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多