我有一个脚本返回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。
答案 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")])
您可以使用old
和new
作为输入变量。
答案 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])
}
}