There is a function setnames built into package data.table for exactly that.
setnames(DT, "b", "d")
It changes the names by reference with no copy at all. Any other method using names(data)<- or names(data)[i]<- or similar will copy the entire object, usually several times. Even though all you're doing is changing a column name.
DT must be type data.table for setnames to work, though. So you'd need to switch to data.table or convert using as.data.table, to use it.
Here is the extract from ?setnames. The intention is that you run example(setnames) at the prompt and then the comments relate to the copies you see being reported by 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.
colnames(data['b']) <- 'd', also not good! As Chase points out, this is the way:colnames(data)[colnames(data) == "b"] <- "d"