| setattr {data.table} | R Documentation |
In data.table, all set* functions change their input by reference. That is, no copy is made at all, other than temporary working memory which is as large as one column. The only other data.table operator that modifies input by reference is :=. Check out the See Also section below for other set* function that data.table provides.
setattr(x,name,value) setnames(x,old,new)
x |
|
name |
The character attribute name. |
value |
The value to assign to the attribute or |
old |
When |
new |
Optional. New column names, must be the same length as columns provided to |
setnames operates on data.table and data.frame not other types like list and vector. It can be used to change names by name with built-in checks and warnings (e.g., if any old names are missing or appear more than once).
setattr is a more general function that allows setting of any attribute to an object by reference.
A very welcome change in R 3.1+ was that 'names<-' and 'colnames<-' no longer copy the entire object as they used to (up to 4 times), see examples below. They now take a shallow copy. The ‘set*' functions in data.table are still useful because they don’t even take a shallow copy. This allows changing names and attributes of a (usually very large) data.table in the global environment from within functions. Like a database.
The input is modified by reference, and returned (invisibly) so it can be used in compound statements; e.g., setnames(DT,"V1", "Y")[, .N, by=Y]. If you require a copy, take a copy first (using DT2=copy(DT)). See ?copy.
Note that setattr is also in package bit. Both packages merely expose R's internal setAttrib function at C level but differ in return value. bit::setattr returns NULL (invisibly) to remind you the function is used for its side effect. data.table::setattr returns the changed object (invisibly) for use in compound statements.
data.table, setkey, setorder, setcolorder, set, :=, setDT, setDF, copy
DF = data.frame(a=1:2,b=3:4) # base data.frame to demo copies and syntax
if (capabilities()["profmem"]) # usually memory profiling is available but just in case
tracemem(DF)
colnames(DF)[1] <- "A" # 4 shallow copies (R >= 3.1, was 4 deep copies before)
names(DF)[1] <- "A" # 3 shallow copies
names(DF) <- c("A", "b") # 1 shallow copy
`names<-`(DF,c("A","b")) # 1 shallow copy
DT = data.table(a=1:2,b=3:4,c=5:6) # compare to data.table
if (capabilities()["profmem"])
tracemem(DT) # by reference, no deep or shallow copies
setnames(DT,"b","B") # by name, no match() needed (warning if "b" is missing)
setnames(DT,3,"C") # by position with warning if 3 > ncol(DT)
setnames(DT,2:3,c("D","E")) # multiple
setnames(DT,c("a","E"),c("A","F")) # multiple by name (warning if either "a" or "E" is missing)
setnames(DT,c("X","Y","Z")) # replace all (length of names must be == ncol(DT))
DT <- data.table(x = 1:3, y = 4:6, z = 7:9)
setnames(DT, -2, c("a", "b")) # NEW FR #1443, allows -ve indices in 'old' argument
DT = data.table(a=1:3, b=4:6)
f = function(...) {
# ...
setattr(DT,"myFlag",TRUE) # by reference
# ...
localDT = copy(DT)
setattr(localDT,"myFlag2",TRUE)
# ...
invisible()
}
f()
attr(DT,"myFlag") # TRUE
attr(DT,"myFlag2") # NULL