user7200033
user7200033

Reputation: 3

Update Data Frame through nested functions in R

I have a small reproducible version of the issue I'm having with my program.

The structure of my code involves nested functions, similar to the one shown below, only more complex.

x <- data.frame(c(1:5),c(0))
colnames(x) <- c("val1", "val2")

foo <- function() {
  for(i in 1:length(x[,1])) {
    bar(i)
  }
  print(x)
}

bar <- function(i) {
   if(x[i,2] == 0) {
    x[i,2] <- 1
    print(x[i,])
  }
  return(x)
}

>foo()
  val1 val2
1    1    1
  val1 val2
2    2    1
  val1 val2
3    3    1
  val1 val2
4    4    1
  val1 val2
5    5    1
  val1 val2
1    1    0
2    2    0
3    3    0
4    4    0
5    5    0

So as the results show, the value is not being returned from the bar() function in order to update the data frame.

What do I need to change in order to return an updated table to the foo() function?

Thanks in advance.

Upvotes: 0

Views: 184

Answers (2)

SeldomSeenSlim
SeldomSeenSlim

Reputation: 841

So I'm a bit confused as to why you need to write a function to accomplish this. By far the simplest solution would just be to subset the dataframe conditionally and assign the value:

  x <- data.frame(c(1:5),c(0))
  colnames(x) <- c("val1", "val2")


  x$val2[x$val2==0]<-1

However, if this is too simplistic an answer, as in the solution needs to scale, I suspect that embedding one of the apply functions would likely work.

Upvotes: 0

manotheshark
manotheshark

Reputation: 4357

It's better to pass the data.frame as an argument instead of hard coding it to the function. Here are some modifications that should accomplish what you're looking for

foo <- function(df) {
  for(i in seq_len(nrow(df))) {
    df[i, ] <- bar(df[i, ])
  }
  print(df)
}

bar <- function(df) {
  if(df[, "val2"] == 0) {
    df[, "val2"] <- 1
    print(df[, ])
  }
  return(df)
}

> foo(x)
  val1 val2
1    1    1
  val1 val2
2    2    1
  val1 val2
3    3    1
  val1 val2
4    4    1
  val1 val2
5    5    1
  val1 val2
1    1    1
2    2    1
3    3    1
4    4    1
5    5    1

Upvotes: 1

Related Questions