Tomas
Tomas

Reputation: 59545

Assign to variable _AND_ keep attributes

I have a variable with a huge matrix; this variable has some attributes, including smaller matrices.

I want to assign something small (like NA) to this variable, so that I can save memory; but I want to keep the attributes.

Is there some elegant way or do I have to do it in some clumsy way with two assignments, second one with mostattributes?

PS: illustrative example

a <- matrix(1:9,3,3)

attr(a, 'ahoj') <- 1:10

a <- NA # attributes lost, I want assignment which keeps them

The only thing I can think of is to replace the assignment with these 3:

empty_a <- NA
mostattributes(empty_a) <- attributes(a)
a <- empty_a

but that's pretty clumsy way :)

Upvotes: 4

Views: 101

Answers (1)

r2evans
r2evans

Reputation: 160667

If you want to replace the values of the object without losing all of the attributes and such, then you can use [<- (though this does preserve its dimensions):

a <- matrix(1:9,3,3)
attr(a, 'ahoj') <- 1:10

a[] <- NA
a
#      [,1] [,2] [,3]
# [1,]   NA   NA   NA
# [2,]   NA   NA   NA
# [3,]   NA   NA   NA
# attr(,"ahoj")
#  [1]  1  2  3  4  5  6  7  8  9 10

Alternative, that does your mostattributes-like operation, with "some" smarts:

copyattributes <- function(x, oldvalue = NULL, remattr = character(0)) {
  oldattr <- attributes(oldvalue)
  clsfun <- class(oldvalue)[1]
  remattr <- unique(c(
    remattr,
    if (exists(clsfun, mode = "function")) {
      names(attributes(match.fun(clsfun)()))
    } else character(0)))
  copyattr <- setdiff(setdiff(names(oldattr), remattr), names(attributes(x)))
  attributes(x) <- c(attributes(x), oldattr[ copyattr ])
  x
}

a <- matrix(1:9,3,3)
attr(a, 'ahoj') <- 1:10
b <- NA
attr(b, "quux") <- "A"
a <- copyattributes(b, a)
a
# [1] NA
# attr(,"quux")
# [1] "A"
# attr(,"ahoj")
#  [1]  1  2  3  4  5  6  7  8  9 10

The remattr tries to use the class of the old object (a) to determine what attributes are always there (e.g., "dim" for matrices, and c("names", "row.names") for frames), and not copy those over. Then it ensures it does not overwrite or delete existing attributes.

Upvotes: 1

Related Questions