Nova
Nova

Reputation: 618

How to create new vector by using conditionals on another vector?

I have a vector, my_class, that is made up of grades. I am trying to generate a new vector, top_grades, that is filled up with grades from my_class that are greater than or equal to 85. I wrote the following code, but the top_grades vector ended up being the size of my_class vector, with all the grades that were under 85 being returned as NA. I think this happens because some indices of top_grades were given no value as the vector was being built.

my_class = c(84, 85, 90) #sample vector
top_grades = c() #create vector
for (i in 1:length(my_class)) { #iterate for each index in the length of my_class
  if (my_class[i] >= 85) {
    top_grades[i] <- my_class[i] #the value of top_grades at index i is the value of my_class at index i
  } else {
    next #go to next index if the value of the grade at that index is lower than 85
  }
}

I solved this problem by finding a handy function online that removes the NA's from a vector.

   top_grades = na.omit(top_grades) #remove NA's from filled vector

My question: Is there a more elegant way to write this loop that builds the top_grades vector without NA's?

Upvotes: 1

Views: 373

Answers (2)

iod
iod

Reputation: 7592

> top_grades<-my_class[my_class>=85]
> top_grades
[1] 85 90

Explanation: If you're using a FOR loop to loop through a vector, you're missing out on the power of R. In this example, you basically want to subset my_class based on the cases that are larger or equal to 85, and place that result into top_grades. my_class>=85 creates a vector (of length(my_class)) with TRUE or FALSE for that condition. This vector is then passed as a subset call on my_class, and this returns only those parts of the vector for which the subset says TRUE.

(a two line way of doing the same would be:

high<-my_class>=85
top_grades<-my_class[high]

which is perfectly equivalent to my one line version)

Upvotes: 1

smanski
smanski

Reputation: 541

You can simplify your code by using

top_grades <- my_class[my_class >= 85]

Note that my_class >= 85 creates a vector of boolean variables, and only the my_class values where the boolean variable is true are kept.

If you are interested in the indices that make up top_grades, you can run

which(my_class >= 85)

Upvotes: 1

Related Questions