Maryam
Maryam

Reputation: 97

pass a list by reference in R function

I have a simple recursion function in R that would modify its input arguments. I use eval.parent(substitute()) in order to apply the changes on the arguments, However I get this error: "invalid (do_set) left-hand side to assignment " Does anyone know how to fix this error? Here is my function:

decompose_clade=function(ind,Small_clades_ind,Remove_tips,Clades){
  Ch=Children(tree,ind)
  if(Ch[1]<length(tree$tip.label)){
    l=Remove_tips
    l=c(l,Ch[1])
    eval.parent(substitute(Remove_tips=l))
    print("tip added=")
    print(Ch[1])
  }else if(length(extract.clade(tree,Ch[1])$tip.label)<4){
    s=Small_clades_ind
    s=c(s,Ch[1])
    eval.parent(substitute(Small_clades_ind=s))
    print("small clade added=")
    print(Ch[1])
  }else if(length(extract.clade(tree,Ch[1])$tip.label)>80){
    decompose_clade(Ch[1],Small_clades_ind,Remove_tips,Clades)
    print("function calls again")
  }else{
   m=Clades
   m=c(m,Ch[1])
    eval.parent(substitute(Clades<-m))
    print("a clade added=")
    print(Ch[1])
  }

} 

Upvotes: 0

Views: 256

Answers (2)

Consistency
Consistency

Reputation: 2922

There is no easy way to have pass-by-reference behaviours in R, with only one exception: environment. I'm not sure if environment suits your need, you can give it a try:

modify_input <- function(x){
    x$z <- 1
}

x <- new.env(parent = emptyenv())
modify_input(x)
x$z

As to the usage, environment supports e$z and e[["z"]] and length(e) just like list, but it doesn't support e[[1]] and things like that. You can think of environment as a dictionary and elements in it have no order. If you want to list all the elements in an environment, you can use ls. And there are ways to transform environment to list (as.list) and vise versa (list2env). Hope it can help.

Upvotes: 3

kangaroo_cliff
kangaroo_cliff

Reputation: 6222

May be you can follow the following approach.

x <- 1
fn <- function() {
    x <<- 2 
}

Now x is 2.

Upvotes: 0

Related Questions