Reputation: 1991
I have a vector v
such as
v = c(0, 0, 1, 1, 1.5, 2, 2, 2, 5, 5, 5, 5, 5, 5, 10)
res = rep(0, length(unique(v)))
for(i in 1:(length(unique(v)))){
res[i] = sum(v == i) / sum(v > i)
}
> res
[1] 0.1818182 0.4285714 0.0000000 0.0000000 6.0000000
[6] 0.0000000
The desire result is as follows:
res = c(2/13, 2/11, 1/10, 3/7, 6/1, 10/0)
How can I write a function in R which gives the desire result?
Upvotes: 1
Views: 53
Reputation: 81713
Another approach using colSums
:
tmp <- unique(v)
colSums(sapply(tmp, "==", v)) / colSums(sapply(tmp, "<", v))
# [1] 0.1538462 0.1818182 0.1000000 0.4285714 6.0000000 Inf
Upvotes: 0
Reputation: 1287
I think you want Count with unique value
for(i in 1:(length(unique(v)-1)))
{
res[i] = length(v[v==unique(v)[i]]) / length(v[v >unique(v)[i]])
}
res
[1] 0.1538462 0.1818182 0.1000000 0.4285714 6.0000000 Inf
res = c(2/13, 2/11, 1/10, 3/7, 6/1, 10/0)
> res
[1] 0.1538462 0.1818182 0.1000000 0.4285714 6.0000000 Inf
Upvotes: 1
Reputation: 61953
Your main problem is that i
isn't necessarily going to be an element of v
. It is just the index you created. Part of the problem is that you need that index because you're trying to use a for loop so you need to know which spot in your result vector to store the result in but really you also need to make sure to grab the appropriate value from the unique values when doing your comparison (ie don't compare directly to i).
This is how I would consider doing it to avoid having to preallocate the result vector
v <- c(0, 0, 1, 1, 1.5, 2, 2, 2, 5, 5, 5, 5, 5, 5, 10)
u <- unique(v)
sapply(u, function(i){sum(v == i)/sum(v > i)}) # can store into res if you want
#[1] 0.1538462 0.1818182 0.1000000 0.4285714 6.0000000 Inf
Notice that here sapply is passing along elements of u
(which are the unique values in v) to the anonymous function I defined so the comparison really is doing what you want it to do here.
Upvotes: 2