【问题标题】:updating column names in multiple dataframes based on the row values in another dataframe in R根据R中另一个数据框中的行值更新多个数据框中的列名
【发布时间】:2023-01-18 01:05:11
【问题描述】:

我有五个数据框(df1、df2、df3、df4、df5),包括需要重命名的多个列。在一个单独的数据框中,它用作重命名的映射(见下表),我有三列,一列包含新变量名称,另外两列包含需要重命名的变量。旧变量 1 指的是 df1、2 和 3,而 old_variables2 指的是 df4 和 df5。

New variables old variables1 old variables2
DPG DPG1, DPG2, DPG3 DPG1, DPG2
LMN LMN1, LMN2, LMN3 LMN1, LMN2
CLG CLG1, CLG2, CLG3 CLG1, CLG2

我需要使用地图数据编写代码,根据地图数据中的新变量列重命名我的五个数据框中的列。例如DPG1、LMN1、CLCG1属于df1,应该重命名为DPG、LMN、CLG。 df2 和 df3 也一样。我尝试使用通用代码,因为信息可能会在我的数据文件中更新。 有人可以给我一些提示吗? 我不知道如何处理旧变量列中每个单元格中以逗号分隔的多个值。

感谢@starja,我想出了一个解决方案,但我仍然对函数的左连接部分有问题,因为包含 by = c("original_variables" = "old_variables1","old_variables2") 是错误的。

cols<- c(old_variables1, old_variables2)

rename_function <- function(col_names, rename_data = rename_info) {
for (col in cols) {
rename_info_clean <- separate_rows(rename_info,all_of(col))
}
data.frame(original_variables = col_names) %>% 
left_join(rename_info_clean , by = c("original_variables" = "old_variables1","old_variables2")) %>% 
mutate(final_name = coalesce(new_variables, original_variables)) %>% 
pull(final_name)
}

【问题讨论】:

  • 换句话说,df1$DPG1df2$DPG2df3$DPG3需要重命名为df1$DPGdf2$DPGdf3$DPG等吗?
  • @AndreWildberg 是的,没错。
  • 您可以尝试使用&lt;&lt;- 进行全局分配,它可以工作,但并不真正推荐。类似于df_list &lt;- list(df1, df2, df3)sapply(1:nrow(df_nm), function(x) colnames(df_list[[x]])[grep(gsub(", ", "|", df_nm$old_variables[x]), colnames(df_list[[x]]))] &lt;&lt;- df_nm$New_variables[x])

标签: r dataframe dictionary rename


【解决方案1】:

如果任务只是删除数字,我们还可以使用一些 regex 来实现更简单的功能。这里使用tidyverse

library(dplyr)
library(stringr)

test_data_1 |>
  rename_with(~ str_extract(., "\D+"))

test_data_2 |>
  rename_with(~ str_extract(., "\D+"))

输出:

  DPG LMN test
1   1   4    a

  DPG LMN other_name
1   2   5          4

感谢@starja 提供的数据。

【讨论】:

    【解决方案2】:

    这是一个使用rename_withtidyverse解决方案:

    library(dplyr)
    rename_info <- data.frame(
      new_variables = c("DPG", "LMN"),
      old_variables = c("DPG1, DPG2, DPG3", "LMN1, LMN2, LMN3"),
      old_variables_2 = c("DPG1, DPG2", "LMN1, LMN2")
    )
    
    test_data_1 <- data.frame(
      DPG1 = 1,
      LMN1 = 4,
      test = "a"
    )
    
    test_data_2 <- data.frame(
      DPG2 = 2,
      LMN2 = 5,
      other_name = 4
    )
    
    rename_function <- function(col_names, rename_data = rename_info) {
      rename_info_clean_1 <- rename_info %>% 
        tidyr::separate_rows(
          old_variables,
          sep = ",[ ]+"
        ) %>% 
        select(new_variables, old_variables)
      rename_info_clean_2 <- rename_info %>% 
        tidyr::separate_rows(
          old_variables_2,
          sep = ",[ ]+"
        ) %>% 
        select(new_variables, old_variables = old_variables_2)
      rename_info_clean <- bind_rows(
        rename_info_clean_1,
        rename_info_clean_2
      ) %>% 
        distinct()
      data.frame(original_variables = col_names) %>% 
        left_join(rename_info_clean, by = c("original_variables" = "old_variables")) %>% 
        mutate(final_name = coalesce(new_variables, original_variables)) %>% 
        pull(final_name)
    }
    
    test_data_1 %>% 
      rename_with(rename_function)
    #>   DPG LMN test
    #> 1   1   4    a
    
    test_data_2 %>% 
      rename_with(rename_function)
    #>   DPG LMN other_name
    #> 1   2   5          4
    

    reprex package (v1.0.0) 创建于 2023-01-17

    基本上,rename_function 首先制作一个 data.frame,其中每个旧/新变量名称组合都在其自己的行中,separate_rows,然后将它与可用的列名称连接起来。当没有匹配项时(例如 test),连接会导致 NAcoalesce 替换为原始名称。

    编辑

    现在重复 separate_rows 步骤,并将 2 列的结果叠加在一起。

    【讨论】:

    • 非常感谢您提供优雅的解决方案。它完美地工作!是否可以在 separate_rows 函数中包含两列?我的数据中还有另一列(想象一下 rename_info 数据框中的两个 old_variables 列。我想知道我是否可以将它包含在代码中,以便我一次性完成两列。
    • 应该是可以的。你能用示例数据更新你的问题吗?
    • 我刚刚更新了它。
    • 查看我更新的功能
    猜你喜欢
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多