1

I am trying to append rows to a dataframe inside a user defined function. I have done this before in a for loop without difficulty, as follows:

t1 <- data.frame(a=character(),
                 b=numeric())
for(i in 1:2){
    tmp.df <- data.frame(a="apple", b=i)
    t1 <- rbind(t1,tmp.df)
}

I get a dataframe with two observations.

But when I try and do a similar thing inside a function, it doesn't work. I have tried debugging the function and at the rbind step it just seems to exit the function without carrying out that step. So the following code ends up with the original empty data frame.

t1 <- data.frame(a=character(),
                 b=numeric())

create.rows <- function(id, it){
  if(it==1){
    
    tmp.df <- data.frame(a=id, b=it)
    t1 <- rbind(t1,tmp.df)
  }else{
    tmp.df <- data.frame(a=id, b=99)
    t1 <- rbind(t1,tmp.df)
  }
}

Why is this happening and what can I do to fix it?

Note that I do not know in advance how many rows there will be in the dataframe so I can't write directly to a particular row.

1
  • 1
    "It doesn't work". What is "it". Just creating a function does nothing. Commented Dec 1, 2020 at 0:43

2 Answers 2

2

Within a function one needs to specify the <<- form of the assignment operator to get R to search through parent environments to find the object on the left side of the assignment operator and assign it a new value.

t1 <- data.frame(a=character(),
                 b=numeric())

create.rows <- function(id, it){
     if(it==1){
          
          tmp.df <- data.frame(a=id, b=it)
          t1 <<- rbind(t1,tmp.df)
     }else{
          tmp.df <- data.frame(a=id, b=99)
          t1 <<- rbind(t1,tmp.df)
     }
}

create.rows(1,1)
create.rows(1,2)
t1

...and the output:

> t1
  a  b
1 1  1
2 1 99

For additional details on behavior of the three forms of the assignment operator (=, <- and <<-), review the help page for assignment operator, where the relevant section says:

The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment.

Sign up to request clarification or add additional context in comments.

6 Comments

the statement: one needs to specify the <<- form of the assignment operator to get R to search through parent environments to find the object on the left side of the assignment operator. is quite misleading. Does that mean that <- , =, -> do not search through the parent environments?? I do believe they do. The difference is that <<- redefines the object in the environment (obviously when the binding of the object is unlocked) while <- does not
Hello @Onyambu. I don't agree with your characterization of my answer. The way I read Software for Data Analysis section 5.4, the point of the <<- operator is to perform non-local assignment from within a function, which by definition, redefines the value of an object in the parent environment.
Thank you so much - I had never come across this assignment operator before.
@Susan - you're welcome. If you found the answer helpful, please accept and/or upvote it. BTW, Ronak Shah's answer also works.
The <- does exactly wjat you stated above too. Thats ehy i daid that the statement is misleading. The main difference between <<- and <- is that the later cannot be used to REDEFINE a variable. Probably your stayement should read one needs to specify the <<- form of the assignment operator to get R to search through parent environments to find the object on the left side of the assignment operator AND REDEFINE IT
|
1

return the changed dataframe at the end of the function.

t1 <- data.frame(a=character(),
                 b=numeric())

create.rows <- function(id, it){

  if(it==1){
    tmp.df <- data.frame(a=id, b=it)
    t1 <- rbind(t1,tmp.df)
  }else{
    tmp.df <- data.frame(a=id, b=99)
    t1 <- rbind(t1,tmp.df)
  }
  return(t1)
}

t1 <- create.rows(1,1)
t1
#  a b
#1 1 1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.