Lfppfs
Lfppfs

Reputation: 124

Vector whose elements add up to a value in R

I'm trying to create a vector whose elements add up to a specific number. For example, let's say I want to create a vector with 4 elements, and they must add up to 20, so its elements could be 6, 6, 4, 4 or 2, 5, 7, 6, whatever. I tried to run some lines using sample() and seq() but I cannot do it.

Any help appreciated.

Upvotes: 2

Views: 68

Answers (2)

d.b
d.b

Reputation: 32548

foo = function(n, sum1){
    #Divide sum1 into 'n' parts
    x = rep(sum1/n, n) 

    #For each x, sample a value from 1 to that value minus one
    f = sapply(x, function(a) sample(1:(a-1), 1))

    #Add and subtract f from 'x' so that sum(x) does not change
    x = x + sample(f)
    x = x - sample(f)

    x = floor(x)
    x[n] = x[n] - (sum(x) - sum1)

    return(x)
}

Upvotes: 2

Spacedman
Spacedman

Reputation: 94182

To divide into 4 parts, you need three breakpoints from the 19 possible breaks between 20 numbers. Then your partitions are just the sizes of the intervals between 0, your partitions, and 20:

> sort(sample(19,3))
[1]  5  7 12
> diff(c(0, 5,7,12,20))
[1] 5 2 5 8

Test, lets create a big matrix of them. Each column is an instance:

> trials = sapply(1:1000, function(X){diff(c(0,sort(sample(19,3)),20))})
> trials[,1:6]
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    1    8   13    3    2
[2,]    4    7   10    2    9    5
[3,]    2   11    1    4    3    7
[4,]   11    1    1    1    5    6

Do they all add to 20?

> all(apply(trials,2,sum)==20)
[1] TRUE

Are there any weird cases?

> range(trials)
[1]  1 17

No, there are no zeroes and nothing bigger than 17, which will be a (1,1,1,17) case. You can't have an 18 without a zero.

Upvotes: 2

Related Questions