【问题标题】:Fully programmatically rename columns in R with dplyr使用 dplyr 完全以编程方式重命名 R 中的列
【发布时间】:2021-05-19 09:22:42
【问题描述】:

我在许多数据框中都有传感器数据,用于几种不同的传感器类型。我需要对数据帧执行 inner_joins 以便最终得到一个数据帧。给定传感器类型的数据帧的列名是相同的,例如

> z501h001

  timeBgn soilTempMean soilTempVar
1 01:00:00     100        4
2 01:30:00     112        6
3 02:00:00     111        6

> z501h002

timeBgn soilTempMean soilTempVar
1 01:00:00     120        4
2 01:30:00     122        6
3 02:00:00     121        5

除了有更多的列。不同类型的传感器的列名称不同(它们都有timeBgn 的共同点)。

我需要(在 R 中)一种灵活的方式来重命名列(这样我就可以知道哪一列对应于哪个传感器)基于为除 timeBgn 之外的所有列的现有列名添加一个后缀(这是由其中 inner_join 将完成)。

这是我正在尝试做的 Python / Pandas 等价物:

def rename_cols_by_sensor(df, sensor_name):
    cols = df.columns
    new_cols = [f'{c}_{sensor_name}' if c!='timeBgn' else c for c in cols] 
    df.columns = new_cols

我在这里找到了大部分解决方案: programmatically rename columns in dplyr

问题是我无法弄清楚如何以编程方式制作 cnames 向量。我不想硬编码所有无数的列名。作为z501h001 的示例,它需要看起来像

cnames <- c('soilTempMean' = 'soilTempMean_z501h001', 'soilTempVar' = 'soilTempVar_z501h001')

后缀(在示例中:_z501h001)可以传递给函数,因此这里无需讨论获取它。使用names(df) 很容易获得原始名称。我只需要知道如何以c("character" = "other_character") 格式将它们组合在一起。

我试过了:

rename_by_loc <- function(df, loc) {
    old_names <- names(df)
    new_names <- c()
    loc = z501h001
    for (name in old_names) {
        if (name != "timeBgn") { 
            new_names <- c(new_names, paste(name, paste(name, loc, sep="_"), sep = " = ") )
        }
    }
    return(new_names)
}

但这给了我像"soilTempMean = soilTempMean_z501h001"这样的名字

我需要将 = 放在字符串之外。我尝试了其他一些事情。没有一个成功。

这个问题在使用 Pandas 时是微不足道的,这让我觉得我错过了关于 R 中的列重命名的一些东西。

谢谢。

【问题讨论】:

    标签: r pandas dataframe


    【解决方案1】:

    我们可以使用mget来获取对象的所有值,对象名称的模式以“z”开头,后跟3位数字,“h”,然后是list中的3位数字,然后使用@ 987654323@ 循环遍历 listrename 除 'timeBgn' 之外的所有列,方法是将 (str_c) 原始列与对象名称连接起来

    library(dplyr)
    library(purrr)
    library(stringr)
    out <- mget(ls(pattern = "^z\\d{3}h\\d{3}$")) %>%
        imap(~  {
                 nm1 <- .y
                 .x %>%
                    rename_with(~ str_c(., "_", nm1), -timeBgn)
               })
    

    输出将是list。如果我们需要更改原始对象中的列名(不推荐),请使用list2env

    list2env(out, .GlobalEnv)
    

    或者使用base R

    v1 <- ls(pattern = "^z\\d{3}h\\d{3}$")
    for(v in v1) {
      tmp <- get(v)
      i1 <- names(tmp) != 'timeBgn'
      names(tmp)[i1] <- paste0(names(tmp)[i1], '_', v)
      assign(v, tmp)
    }
                  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多