Josh
Josh

Reputation: 321

How can I create a for-loop to count the number of values within a vector that fall between a set boundary?

I'm trying to set an upper and lower boundary of a vector by simply adding and subtracting a set value from each index. I then want to create a loop that tells me for each value (i) in the vector, how many other points within the vector falls within that boundary.

Essentially creating a pseudo-density calculation based on how many values fall within the established range.

I have my vector "v" that contains random values. I then add/subtract three to it to get the upper and lower ranges. But can't create a loop that will count how many other values from that vector fall within that.

v <- c(1, 3, 4, 5, 8, 9, 10, 54)

for (i in v){
  vec2 <- (vec +3 > vec[i] & vec -3 < vec[i])
  }
vec2

I get NA's from this code.

I've also tried indexing the vec +/- 3 and it also didn't work.

vec2 <- (vec[i] +3 > vec[i] & vec - 3 < vec[i))

What I want is for every "i" value in the vector, I want to know how many points fall within that value + and -3.

i.e. first value being 1: so the upper limit would be 4 and the lower would be -2. I want it to count how many values remaining in the vector, fall within this. Which would be 3 for the first index (if it includes itself).

vec2 = (3, 4, 3, . . . )

Upvotes: 1

Views: 2584

Answers (2)

Dunois
Dunois

Reputation: 1843

Are you looking for something like this? Your code doesn't work because your syntax is incorrect.

vec <- c(1, 3, 4, 5, 8, 9, 10, 54) #Input vector

countvalswithin <- vector() #Empty vector that will store counts of values within bounds

#For loop to cycle through values stored in input vector
for(i in 1:length(vec)){
  currval <- vec[i] #Take current value
  lbound <- (currval - 3) #Calculate lower bound w.r.t. this value
  ubound <- (currval + 3) #Calculate upper bound w.r.t. this value

  #Create vector containing all values from source vector except current value
  #This will be used for comparison against current value to find values within bounds.
  othervals <- subset(vec, vec != currval)

  currcount <- 1 #Set to 0 to exclude self; count(er) of values within bounds of current value

  #For loop to cycle through all other values (excluding current value) to find values within bounds of current value
  for(j in 1:length(othervals)){

    #If statement to evaluate whether compared value is within bounds of current value; if it is, counter updates by 1
    if(othervals[j] > lbound & othervals[j] <= ubound){
      currcount <- currcount + 1 
    }

  }

  countvalswithin[i] <- currcount #Append count for current value to a vector

}

df <- data.frame(vec, countvalswithin) #Input vector and respective counts as a dataframe

df

 #    vec countvalswithin
 #  1   1               3
 #  2   3               4
 #  3   4               3
 #  4   5               4
 #  5   8               3
 #  6   9               3
 #  7  10               3
 #  8  54               1

Edit: added comments to the code explaining what it does.

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389012

In your for loop we can loop over every element in v, create range (-3, +3) and check how many of the elements in v fall within that range and store the result in new vector vec2.

vec2 <- numeric(length = length(v))
for (i in seq_along(v)) {
   vec2[i] <- sum((v  >= v[i] - 3) & (v <= v[i] + 3))
}
vec2
#[1] 3 4 4 4 4 3 3 1

However, you can avoid the for loop by using mapply

mapply(function(x, y) sum(v >= y & v <= x), v + 3, v - 3)
#[1] 3 4 4 4 4 3 3 1

Upvotes: 1

Related Questions