Reputation: 6477
I have a objects of certain class which contain several matrices, and I would like to build a function which access and possibly modifies subset of such matrix. For example:
foo<-list(x=diag(1:4),y=matrix(1:8,2,4))
class(foo)<-"bar"
attr(foo,"m")<-4
attr(foo,"p")<-2
rownames(foo$x)<-colnames(foo$x)<-colnames(foo$y)<-c("a.1","b.1","b.2","c.1")
attr(foo,"types")<-c("a","b","b","c")
Now I could access and modify certain elements like this:
foo$x[attr(foo,"types")%in%c("c","b"),attr(foo,"types")%in%c("c","b")]
foo$x[attr(foo,"types")%in%c("c","b"),attr(foo,"types")%in%c("c","b")]<-matrix(5,3,3)
But instead of the above, I would like to construct a following type of function:
modify<-function(object,element,types){
# check that the object is proper class,
# and the element and the types are found in the object
# this returns to the local copy of the corresponding subset:
object[[element]][attr(object,"types")%in%types,attr(object,"types")%in%types]
}
For accessing the above function is ok, but what if I want to modify the original object? Obviously this doesn't work:
modify(foo,"x",c("c","b"))<-matrix(5,3,3)
Error in modify(foo, "x", c("c", "b")) <- matrix(5, 3, 3) :
could not find function "modify<-
Is it possible to get that work somehow? If not, one option I could think of is adding argument replace.with
to function modify
and then making the assignment first to the local copy and then copying the change to the object in the calling environment using assign
function. For this I would need to find the original object in the calling environment, but I'm not sure how to do that.
Upvotes: 0
Views: 275
Reputation: 6477
Ok, I found a solution myself with a help of old post from R-help by Brian Ripley:
foo<-list(x=diag(1:4),y=matrix(1:8,2,4))
class(foo)<-"bar"
attr(foo,"m")<-4
attr(foo,"p")<-2
rownames(foo$x)<-colnames(foo$x)<-colnames(foo$y)<-c("a.1","b.1","b.2","c.1")
attr(foo,"types")<-c("a","b","b","c")
`modify<-` <- function(x, element, subset,value) UseMethod("modify<-")
`modify<-.bar` <- function(x, element, subset,value) {
x[[element]][,attr(foo,"types")%in%subset] <- value
x }
modify(foo,"x",c("c","b"))<-matrix(5,3,3)
foo$x
a.1 b.1 b.2 c.1
a.1 1 0 0 0
b.1 0 5 5 5
b.2 0 5 5 5
c.1 0 5 5 5
Upvotes: 0
Reputation: 55350
With the caveat that this is generally frowned upon, you can use the following:
From the target environment, set a variable to the environment and then pass that as an argument to your function which you can use in assign
, get
etc
en <- environment()
myfunc <- function(..., en=en) {
. etc .
assign("varname", envir=en)
}
Note that if you are simply changing attributes, the setattr
function of the data.table package already implements this quote nicely:
setattr(x,name,value)
Upvotes: 1