[R] modifynig some elements of a vector
Petr Savicky
savicky at praha1.ff.cuni.cz
Thu Feb 10 16:26:46 CET 2011
On Thu, Feb 10, 2011 at 12:50:03PM +0100, Eric Elguero wrote:
> He everybody,
>
> I want to add 1 to some elements of a vector:
>
> x is a vector
> u is a vector of idices, that is, integers
> assumed to be within the range 1..length(x)
> and I want to add 1 to the elements of x
> each time their index appears in u
>
> x[u]<-x[u]+1 works only when there are no
> duplicated values in u
>
> I found this solution:
>
> tu <- table(u)
> indices <- as.numeric(names(tu))
> x[indices] <- x[indices]+tu
>
> but it looks ugly to me and I would
> prefer to avoid calling the function 'table'
> since this is to be done millions of times
> as part of a simulation program.
If we start with a zero vector x, then the operation,
which you ask for, is equivalent to computing the
frequency table of u. So, i think, using function table()
may be adequate. However, let me suggest a slightly
different code
n <- 8
x <- rep(0, times=8)
u <- c(1, 2, 5, 2, 5, 1, 2, 8, 2, 1)
x <- x + unclass(table(factor(u, levels=1:n)))
x
1 2 3 4 5 6 7 8
3 4 0 0 2 0 0 1
Another solution may be used, if the vectors u all have the
same length (not only the same range of values). Then it is
possible to compute first the frequency table for each
component of u separately in different rows of a matrix x
m <- 10
x <- matrix(0, nrow=m, ncol=n)
x[cbind(1:m, u)] <- x[cbind(1:m, u)] + 1
This may be repeated for different vectors u and when all
repetitions are finished, then the final result may
be obtained as
colSums(x)
[1] 3 4 0 0 2 0 0 1
Hope this helps.
Petr Savicky.
More information about the R-help
mailing list