【问题标题】:slick way to rename variables across different databases跨不同数据库重命名变量的巧妙方法
【发布时间】:2017-01-07 08:20:44
【问题描述】:

我使用来自不同来源的数据集。通常不同的来源会为同一个变量提供不同的名称。例如,来自源 A 的变量将被称为“Year”,但来自源 B 的变量将被命名为“YEAR”。或者 A 中的“Revenue”和 B 中的“TOT.REV”。我想编写一个脚本,重命名所有不同来源的变量并为它们提供一致的名称。

现在我正在使用dplyr::rename 执行此操作,但考虑到大量变量,管理起来非常可怕且笨拙。我现在的样子是这样的

rename(df, Year = YEAR, Month = MONTH, Revenue = TOT.REV, ...)

除了我在一个列表中循环它,该列表包含来自不同来源的所有数据框。

问题是,如果我想更改任何内容,我必须在脚本中维护这个庞大的列表。不是很方便,也很丑陋。我想用我可以在某处的电子表格中维护的参考表来做到这一点。你知道有什么巧妙的方法吗?提前致谢。 :)

【问题讨论】:

  • 不精确映射的函数将成为您的朋友 - 即,也许您的第一步应该是 tolower() 或类似的东西,以便在相同的情况下获得所有内容,如果您可以使用 make.names()不必担心空格或其他非标准字符。这将使您的代码更加灵活,因此 TOT.REVTOT.revtot rev 不必分别进行显式编码。
  • 就我个人而言,我不明白在 R 中维护数据框或命名向量(可能还有附带的函数)比维护电子表格(和附带的函数)更难,但可以肯定 - 你可以使用电子表格。什么东西阻止你?只需在当前数据名称和参考名称之间进行左连接或匹配即可。
  • “只需在当前数据名称和参考名称之间进行左连接或匹配即可。”是的!这正是我想要的!但是,呃……我该怎么做? (对不起):'(
  • 你卡在哪里了?查看?match?merge?dplyr::left_join 底部的示例。我不知道如何为您提供的内容提供更多帮助...如果您创建 reproducible example - 创建一个小型查找表和几个示例数据框(它们甚至不需要行 - 只需列名) 并试一试。你大概能猜出来。如果您遇到困难,请发布您的示例以及您尝试过的内容,并确保您清楚预期的输出。
  • 您的问题表明您正在使用数据库。您可以编写自定义视图来重命名数据库中的列吗?

标签: r list dplyr rename


【解决方案1】:

您可以从gdata 使用rename.vars

fromnames <- c("speed", "dist")
tonames <- c("Velocity", "Distance")

cars_new <- gdata::rename.vars(cars, fromnames, tonames)

您可以将这两个名称向量保存在 CSV 文件或其他文件中。

【讨论】:

  • 给了我“在 df 中找不到的一些来自名称”的错误消息。当我将其限制为 int(fromnames, names(df)) 时,我收到“from and to not same length”错误消息。因为我有多个数据源,所以肯定有 fromnames 不在 tonames 中
  • 如果您在数据框中有fromnamestonames,您可以使用subset(namesdf, fromnames %in% names(df)),并在rename.vars 中应用它们
【解决方案2】:

执行此操作的一个简单方法是维护一个名称查找表,该表定义了从数据集中的名称到一组通用引用名称的映射。此表将有两列:

  1. name 列用于存储数据集中的名称。
  2. reference 列,用于对应您要映射到的参考名称。

例如,可以将此名称查找表维护为名为@9​​87654323@ 的 CSV 文件:

   name, reference
   Year, YEAR
  Month, MONTH
Revenue, Total Revenue
   YEAR, YEAR
  MONTH, MONTH
TOT.REV, Total Revenue

然后可以将这个 CSV 文件读入 R:

names.table <- read.csv("/path/to/names.table.csv", header=TRUE, strip.white=TRUE, stringsAsFactors=FALSE)
print(names.table)
##     name     reference
##1    Year          YEAR
##2   Month         MONTH
##3 Revenue Total Revenue
##4    YEAR          YEAR
##5   MONTH         MONTH
##6 TOT.REV Total Revenue

重要的是我们指定strip.white=TRUEstringsAsFactors=FALSE 删除所有前导和尾随空格并将条目保留为字符串。

那么,假设我们有数据集(作为数据框),其列名位于names.tablename 列中,例如:

df1 <- data.frame(Year = c(2014, 2014), Month=c("Jan", "Feb"), Revenue=c(124.5, 123.5), stringsAsFactors=FALSE)
print(df1)
##  Year Month Revenue
##1 2014   Jan   124.5
##2 2014   Feb   123.5
df2 <- data.frame(YEAR = c(2015, 2015), MONTH=c("Jan", "Feb"), TOT.REV=c(154.5, 132.5), stringsAsFactors=FALSE)
print(df2)
##  YEAR MONTH TOT.REV
##1 2015   Jan   154.5
##2 2015   Feb   132.5
df3 <- data.frame(YEAR = c(2016, 2016), Month=c("Jan", "Feb"), TOT.REV=c(154.5, 132.5), stringsAsFactors=FALSE)
print(df3)
##  YEAR Month TOT.REV
##1 2016   Jan   154.5
##2 2016   Feb   132.5

可以通过以下方式映射这些名称:

colnames(df1) <- names.table$reference[match(colnames(df1), names.table$name)]
print(df1)
##  YEAR MONTH Total Revenue
##1 2014   Jan         124.5
##2 2014   Feb         123.5
colnames(df2) <- names.table$reference[match(colnames(df2), names.table$name)]
print(df2)
##  YEAR MONTH Total Revenue
##1 2015   Jan         154.5
##2 2015   Feb         132.5
colnames(df3) <- names.table$reference[match(colnames(df3), names.table$name)]
print(df3)
##  YEAR MONTH Total Revenue
##1 2016   Jan         154.5
##2 2016   Feb         132.5

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-16
    • 2020-01-20
    • 2013-01-21
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    相关资源
    最近更新 更多