There's probably a better way to do this but I think this will generate what you want: nsplit = function(X,n){ p = X/sum(X) diff(round(n*cumsum(c(0,p)))) } where `X` is a vector of sizes and `n` in the total. Example: > nsplit(c(1,2,3,4,5),123) [1] 8 17 24 33 41 Those numbers sum to 123 and are approximately in the ratio 1:2:3:4:5. See also this: > nsplit(c(1,2,3,4,5),10*sum(1:5)) [1] 10 20 30 40 50 Note if any of the ratios are small or `n` is small then you will get zeroes: > nsplit(c(1,2,3,4,50),20) [1] 0 1 1 1 17 I think you can then feed those numbers into `spsample` to generate points, but you'll have to do it one polygon feature at a time since `spsample` will only handle a single `n` argument.