Jennifer
Jennifer

Reputation: 165

R indexing a function under an if else statement inside a for loop and returning correct values

I'm having trouble with indexing a function correctly so that it would return the correct values. The function is only applied when an if condition is met, and the ifelse statement is in a for loop.

I've simplified my function and dataset to make the example reproducible here - the way I wrote it currently is not very efficient, but I just want to make sure the indexing works so that I can try applying this back to my more complicated dataset, then work on optimizing later on.

First I start with some data:

var1 <- seq(100, 500, 100)
matrix1 <- matrix(1:12, ncol=2)
matrix2 <- matrix(c(1,2,5,6,8,9,11,12,14,15,17,20), ncol=2)
matrix3 <- matrix(seq(1,34,3), ncol=2)
list1 <- list(matrix1, matrix2, matrix3)

I have a function that takes in a data frame like below:

func1 <- function(df1) {
  data1 <- df1[,1]
  data2 <- df1[,2]
  data3 <- vector()
  data3[i] <- sum(data1, data2)
  return(data3)
}

And my for loop looks like below:

for (i in (1:3)) {
  vec1 <- var1
  vec2 <- diff(unlist(list1[[i]])[,1])
  df1 <- matrix()
  df1 <- cbind(vec1, vec2)
  len <- length(which(vec2<3))
  if (len>1) {
    func1(df1)
  }
  else data3 <- NA
  print(data3)
}

I'm trying to only apply func1 if my df1 passes the length test, and if it doesn't meet the length requirement, I want to give it an NA value.

When i=1, len=5 and data3=1505; when i=2, len=4 and data3=1508; when i=3, len=0 so data3=NA. In short, the result I want to return from the for loop is data3 = c(1505, 1508, NA).

However, I can't get that result now, and since individually running for i=1 i=2 and i=3 works, I'm suspecting that I'm having an index issue (probably inside func1 I suppose) but can't figure it out. Can anyone give me some suggestions?

Upvotes: 0

Views: 730

Answers (2)

ThomasIsCoding
ThomasIsCoding

Reputation: 101753

I think you had a typo in your function func1, which should be

func1 <- function(df1) {
  data1 <- df1[,1]
  data2 <- df1[,2]
  data3 <- vector()
  data3 <- sum(data1, data2)
  return(data3)
}


data3 <- c()
for (i in (1:3)) {
  vec1 <- var1
  vec2 <- diff(unlist(list1[[i]])[,1])
  df1 <- matrix()
  df1 <- cbind(vec1, vec2)
  len <- length(which(vec2<3))
  if (len>1) {
    r <- func1(df1)
  }
  else r <- NA
  data3 <- c(data3,r)
}

After fixing that, you will get the output

> data3
[1] 1505 1508   NA

Upvotes: 1

David Ranzolin
David Ranzolin

Reputation: 1084

I adjusted the loop syntax a bit:

data3 <- vector(length = 3, mode = "numeric")
for (i in 1:3) {
  vec1 <- var1
  vec2 <- diff(unlist(list1[[i]])[,1])
  df1 <- matrix()
  df1 <- cbind(vec1, vec2)
  len <- length(which(vec2<3))
  if (len>1) {
    v <- func1(df1)
    v <- v[!is.na(v)] #when i = 2, func1 returns a vector of length 2
    data3[[i]] <- v
  }
  else {
    data3[[i]] <- NA
  }
}

data3
[1] 1505 1508   NA

Upvotes: 0

Related Questions