重命名R中的一个命名列

use*_*199 17 r dataframe

我想更新数据帧的一列,使用其原始名称引用它,这可能吗?比如说我有表'数据'

a b c  
1 2 2  
3 2 3  
4 1 2
Run Code Online (Sandbox Code Playgroud)

我想将列b的名称更新为'd'.我知道我可以用

colnames(data)[2] <- 'd'  
Run Code Online (Sandbox Code Playgroud)

但是我可以通过专门引用b来进行更改,例如

colnames(data)['b'] <- 'd'  
Run Code Online (Sandbox Code Playgroud)

这样,如果数据帧的列顺序发生更改,则仍会更新正确的列名.

提前致谢

Mat*_*wle 27

正是这个功能setnames内置了一个功能data.table.

setnames(DT, "b", "d")
Run Code Online (Sandbox Code Playgroud)

它通过引用更改名称,完全没有副本.使用names(data)<-names(data)[i]<-类似的任何其他方法将复制整个对象,通常是几次.即使您正在做的只是更改列名称.

DT类型必须data.tablesetnames工作,虽然.所以你需要切换到data.table或转换as.data.table使用它来使用它.

这是摘录?setnames.目的是您example(setnames)在提示符下运行,然后注释与您看到的报告副本相关tracemem.

DF = data.frame(a=1:2,b=3:4)       # base data.frame to demo copies
tracemem(DF)
colnames(DF)[1] <- "A"             # 4 copies of entire object
names(DF)[1] <- "A"                # 3 copies of entire object
names(DF) <- c("A", "b")           # 2 copies of entire object
`names<-`(DF,c("A","b"))           # 1 copy of entire object
x=`names<-`(DF,c("A","b"))         # still 1 copy (so not print method)

# What if DF is large, say 10GB in RAM. Copy 10GB just to change a column name?

DT = data.table(a=1:2,b=3:4,c=5:6)
tracemem(DT)
setnames(DT,"b","B")               # by name; no match() needed. No copy.
setnames(DT,3,"C")                 # by position. No copy.
setnames(DT,2:3,c("D","E"))        # multiple. No copy.
setnames(DT,c("a","E"),c("A","F")) # multiple by name. No copy.
setnames(DT,c("X","Y","Z"))        # replace all. No copy.
Run Code Online (Sandbox Code Playgroud)

  • @Tyler r-devel上有两个(相当长的)线程:[加速感知](http://r.789695.n4.nabble.com/speeding-up-perception-tp3640920.html)和(也许)最相关的)[混淆了NAMED](http://r.789695.n4.nabble.com/Confused-about-NAMED-tp4103326.html)和其他可能. (2认同)
  • @MatthewDowle - 刚刚在你的例子中添加了一个`tracemem`测试,只是b/c它的变量R的行为是多么有趣,而b/c我有点像`4,3,2,1的倒计时,... data.table`. (2认同)

Cha*_*ase 11

这似乎是一个黑客攻击,但首先想到的是使用grepl()足够详细的搜索字符串来获取你想要的列.我相信有更好的选择:

dat <- data.frame(a = 1:3, b = 1:3, c = 1:3)
colnames(dat)[grepl("b", colnames(dat))] <- "foo"
dat
#------
  a foo c
1 1   1 1
2 2   2 2
3 3   3 3
Run Code Online (Sandbox Code Playgroud)

正如乔兰在下面指出的那样,我使事情过于复杂......根本不需要正则表达式.这样也可以节省一些字符.

colnames(dat)[colnames(dat) == "foo"] <- "bar"
#------
  a bar c
1 1   1 1
2 2   2 2
3 3   3 3
Run Code Online (Sandbox Code Playgroud)

  • 或者您可以使用`colnames(dat)=='b'`简单地索引列名称,但无论您做什么,它都将是循环的. (6认同)

Sam*_*rke 9

截至2014年10月,现在可以在dplyr中轻松完成包中:

rename(data, d = b)
Run Code Online (Sandbox Code Playgroud)