BallerNacken
BallerNacken

Reputation: 355

R - write value into variable after two statements

I have a for loop with two if statements. it all works fine, except that I would like to add the values passing the second if statement to the variable v1. I assign the variable first and the variable gets filled with a lot of NA's and the three values I am expecting. But I want only those three values in the variable.

So instead of writing only the i that fulfills the requirements, every single i gets written into the variable.

v1 <- c()

for(i in seq_along(y$values)){
  if(y$lengths[i] < 500 && y$values[i] == TRUE){
    y$values[i] <- FALSE
  }
  if(y$lengths[i] > 500 && y$values[i] == TRUE){
    print(y$lengths[i])
    v1[[i]] <- y$lengths[i]
  }
}

I had a look at the apply functions, but couldn't really figure out how to use both if statements in apply.

The data is a large logical vector. I use y <- rle(vec) on that vector, which gives me y$lengths (everything between 1 and a few hundred thousand) and y$values (TRUE and FALSE).

The desired result is the rle lengths where >500 and TRUE are true.:

[1] 5120
[1] 16630
[1] 10188

Which the print command gives me just fine.

dput(y$length) gives me:

c(129719L, 1L, 79337L, 2L, 4L, 1L, 3L, 1L, 2L, 1L, 1L, 1L, 4L, 
2L, 2L, 3L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 5L, 1L, 3L, 1L, 
6L, 1L, 5120L, 1L, 39L, 1L, 12L, 1L, 121L, 1L, 14L, 1L, 6L, 1L, 
3L, 1L, 3L, 1L, 2L, 1L, 6L, 1L, 11L, 1L, 9L, 1L, 10L, 2L, 6L, 
1L, 2L, 2L, 1L, 1L, 7L, 2L, 4L, 1L, 2L, 1L, 4L, 1L, 3L, 2L, 5L, 
1L, 5L, 4L, 8L, 1L, 4L, 1L, 4L, 2L, 2L, 2L, 9L, 1L, 2L, 1L, 2L, 
1L, 3L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 3L, 3L, 1L, 
7L, 1L, 1L, 1L, 1L, 2L, 6L, 2L, 2L, 1L, 2L, 4L, 3L, 1L, 1L, 1L, 
4L, 3L, 2L, 1L, 5L, 5L, 2L, 2L, 3L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 
4L, 2L, 2L, 1L, 1L, 1L, 4L, 1L, 1L, 3L, 4L, 2L, 1L, 1L, 13L, 
1L, 3L, 2L, 3L, 1L, 9L, 1L, 1L, 1L, 1L, 2L, 3L, 1L, 4L, 1L, 13L, 
1L, 3L, 1L, 4L, 1L, 8L, 1L, 7L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 3L, 
1L, 4L, 1L, 2L, 2L, 5L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 4L, 3L, 
3L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 3L, 1L, 2L, 1L, 4L, 1L, 9L, 2L, 
6L, 1L, 14L, 1L, 2L, 1L, 6L, 1L, 16630L, 7L, 1L, 3L, 2L, 3L, 
1L, 4L, 3L, 4L, 1L, 1L, 2L, 7L, 1L, 1L, 1L, 1L, 1L, 8L, 1L, 5L, 
1L, 6L, 1L, 1L, 3L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 
1L, 1L, 1L, 6L, 1L, 5L, 1L, 2L, 2L, 3L, 1L, 5L, 2L, 3L, 1L, 2L, 
2L, 10L, 1L, 4L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 7L, 3L, 
1L, 1L, 4L, 1L, 1L, 1L, 10L, 1L, 2L, 2L, 3L, 1L, 3L, 5L, 2L, 
3L, 1L, 1L, 2L, 1L, 1L, 3L, 1L, 4L, 3L, 1L, 1L, 1L, 1L, 2L, 2L, 
1L, 4L, 2L, 1L, 1L, 3L, 1L, 1L, 2L, 1L, 4L, 1L, 1L, 3L, 4L, 2L, 
1L, 2L, 1L, 1L, 3L, 1L, 2L, 1L, 2L, 1L, 3L, 1L, 2L, 1L, 3L, 1L, 
1L, 1L, 3L, 2L, 12L, 1L, 3L, 2L, 2L, 1L, 1L, 2L, 7L, 1L, 2L, 
1L, 1L, 2L, 1L, 1L, 7L, 1L, 2L, 1L, 4L, 1L, 7L, 1L, 4L, 1L, 1L, 
1L, 6L, 1L, 6L, 1L, 6L, 2L, 14L, 1L, 5L, 1L, 9L, 1L, 1L, 1L, 
1L, 2L, 39L, 1L, 20L, 1L, 1L, 1L, 6L, 1L, 9L, 2L, 5L, 1L, 7L, 
1L, 16L, 1L, 22L, 1L, 1L, 1L, 10L, 1L, 20L, 1L, 18L, 1L, 20L, 
1L, 3L, 1L, 2L, 1L, 2L, 1L, 5L, 1L, 9L, 1L, 3L, 1L, 3L, 1L, 15L, 
1L, 10L, 1L, 40L, 1L, 30L, 1L, 111L, 1L, 314L, 1L, 9L, 1L, 10188L, 
4L, 88L, 1L, 8L, 1L, 1L, 1L, 1L, 1L, 15L, 1L, 24L, 1L, 1L, 2L, 
3L, 1L, 16L, 1L, 3L, 1L, 4L, 2L, 2L, 2L, 1L, 2L, 5L, 2L, 2L, 
7L, 1L, 1L, 3L, 2L, 3L, 7L, 2L, 1L, 1L, 6L, 1L, 4L, 2L, 2L, 1L, 
2L, 1L, 1L, 1L, 13L, 1L, 2L, 1L, 2L, 1L, 3L, 1L, 3L, 1L, 4L, 
1L, 16L, 1L, 4071L, 5L, 162912L, 1L, 6L, 1L, 280986L)

Upvotes: 0

Views: 123

Answers (2)

user3466328
user3466328

Reputation: 418

This seems to work with the sample data I inferred by reading your question:

y<-data.frame(lengths=seq(100,900,100), 
              values=c("TRUE", "FALSE", "TRUE", "FALSE", "TRUE", "FALSE", "TRUE", "FALSE", "TRUE"))
v1 <- c()

for(i in seq_along(y$values)){
  if(y$lengths[i] < 500 && y$values[i] == TRUE){
y$values[i] <- FALSE
  }
  if(y$lengths[i] > 500 && y$values[i] == TRUE){
#print(y$lengths[i])
ifelse(length(v1)>0, v1<-rbind(v1, y$lengths[i]), v1<-y$lengths[i])
#v1 <- rbind(y$lengths[i])
  }
}

**

> v1
   [,1]
v1 700
   900

**

Upvotes: 0

Arlo Randall
Arlo Randall

Reputation: 46

You can get the final v1 vector very efficiently without loops or apply like this:

v1 <- y$lengths[y$lengths > 500 & y$values == TRUE]

If you want to use loops here are two options:

(1) You can append to v1 like this:

v1 <- c()
for(i in seq_along(y$values)){
  if(y$lengths[i] < 500 && y$values[i] == TRUE){
    y$values[i] <- FALSE
  }
  if(y$lengths[i] > 500 && y$values[i] == TRUE){
    print(y$lengths[i])
    v1 <- c(v1, y$lengths[i])
  }
}

(2) Appending like this can get really slow if the vector v1 gets really long. As an alternative you can preallocate then exclude the NAs in the end like this:

v1 <- rep(NA, length)
for(i in seq_along(y$values)){
  if(y$lengths[i] < 500 && y$values[i] == TRUE){
    y$values[i] <- FALSE
  }
  if(y$lengths[i] > 500 && y$values[i] == TRUE){
    print(y$lengths[i])
    v1[i] <- y$lengths[i]
  }
}
v1 <- v1[!is.na(v1)]

Upvotes: 1

Related Questions