marianess
marianess

Reputation: 115

How many elements of a vector are smaller or equal to each element of this vector?

I am interested in writing a program that gives the number of elements of vector x that are smaller or equal to any given value within vector x.

Let's say

x = [1,3,8,7,6,4,3,10,12]

I want to calculate the number of elements within x which are smaller or equal to 1, to 3, to 8 etc. For example the fifth element of x[5] is 6 and the number of elements smaller or equal to 6 equals to 5. However, I only know how to do an element-wise comparison, e.g x[1]<=x[3]

I suppose that I will be using the for loop and have something like this here:

for (i in length(x)){
       if (x[i]<=x[i]){
       print(x[i])}
       # count number of TRUEs
}

However, this code obviously does not do what I want.

Upvotes: 1

Views: 427

Answers (4)

lmo
lmo

Reputation: 38510

Another alternative is to use rank, which ranks the values. Setting the ties.method argument to "max" retrieves the inclusive value ("<=" versus "<").

rank(x, ties.method="max")
[1] 1 3 7 6 5 4 3 8 9

Upvotes: 3

akrun
akrun

Reputation: 887203

We can use findInterval

findInterval(x, sort(x))
#[1] 1 3 7 6 5 4 3 8 9

Upvotes: 3

Sotos
Sotos

Reputation: 51592

You can also use the *apply family as follows,

sapply(x, function(i) sum(x <= i))
#[1] 1 3 7 6 5 4 3 8 9

Upvotes: 3

Roland
Roland

Reputation: 132706

Use outer to make all comparisons at once:

outer(x, x, "<=")
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8] [,9]
# [1,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE TRUE
# [2,] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE TRUE
# [3,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE TRUE
# [4,] FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE TRUE
# [5,] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE TRUE
# [6,] FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE TRUE
# [7,] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE TRUE
# [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE TRUE
# [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE

colSums(outer(x, x, "<="))
#[1] 1 3 7 6 5 4 3 8 9

Upvotes: 5

Related Questions