当某些列名称可能不存在时,使用data.table :: setnames()

时间:2015-03-31 23:44:47

标签: r data.table

我有一个脚本返回data.table,其中包含一组列。我想重命名其中一些列,但setnames如果不是全部存在则会中断。有没有办法重命名没有循环+错误捕捉或与现有名称相交?

iris.dt <- data.table(iris)
# First time works fine
setnames(iris.dt, c("Sepal.Length", "Sepal.Width"), c("length", "width"))
# Second time fails because columns no longer exist
setnames(iris.dt, c("Sepal.Length", "Sepal.Width"), c("length", "width"))
# Error in setnames(iris.dt, c("Sepal.Length", "Sepal.Width"), c("length",
# :Items of 'old' not found in column names: Sepal.Length,Sepal.Width

setnames(..., allow=T)这样的东西是理想的。

修改:将其归档为FR on Github

4 个答案:

答案 0 :(得分:2)

这个修订过的setnames函数起到了作用:

Setnames <- function(x, old, new, allow.absent.cols=F) {
  if (!allow.absent.cols) {
    setnames(x, old, new)
  } else {
    old.intersect <- intersect(old, names(x))
    common.indices <- old %in% old.intersect
    new.intersect <- new[common.indices]
    setnames(x, old.intersect, new.intersect)
  }
}

答案 1 :(得分:2)

你可以试试&#34; one-liner&#34;

library(data.table)
iris.dt <- data.table(iris)

setnames(iris.dt,c("Sepal.Length", "Sepal.Width")[names(iris.dt) %chin% c("Sepal.Length", "Sepal.Width")], c("length", "width")[names(iris.dt) %chin% c("Sepal.Length", "Sepal.Width")])

您可以使用oldnew作为输入变量。

答案 2 :(得分:2)

data.table v1.12.0(2019年1月13日)开始,这是setnames的参数:

setnames(..., skip_absent=TRUE)  # FALSE by default.

答案 3 :(得分:1)

另一种方法改编自arunsrinivasan对Github FR的建议:

Setnames <- function(x, old, new, allow.absent.cols=F) {
  if (!allow.absent.cols) {
    setnames(x, old, new)
  } else {
    ix <- match(names(x), old, 0L)
    setnames(x, old[ix], new[ix])
  }
}