Dear list Suppose I have the following vector: x <- c(3,4,2,5,6) Obviously, this sums to 20. Now, I want to have a second vector, call it x2, that sums to x where 5 <= x <= 20, but there are constraints. 1) The new vector must be same length as x 2) No element of the new vector can be 0 3) Element x2[i] of the new vector cannot be larger than element x[i] of the original vector 4) Ordering is not important The following would be an example of what I would want if the user wanted the vector x2 to sum to 19 x2 <- c(2,4,2,5,6) Or, because ordering is not important, this is acceptable x2 <- c(3,3,2,5,6) Whereas this would not be appropriate x3 <- c(4, 2,2,5,6) Because element x3[1] is larger than x[1] even though it sums to 19. Ideally, the function would take as input the original vector, x, and the number that the new vector would sum to. In this example, the vector could sum to any number 5 through 20. For example, myFun <- function(x, sumto) ... details ... Is there a preexisiting function that would already do this? I have spent too much (unsuccessful) time trying to write a function of my own but can't seem to get this to work properly. Any hints would be greatly appreciated. Harold [[alternative HTML version deleted]]
Dear Harold package "partitions" does almost this: > library(partitions) > x <- 1+restrictedparts(15,5) > x[,1:10] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [1,] 16 15 14 13 12 11 10 [2,] 1 2 3 4 5 6 7 [3,] 1 1 1 1 1 1 1 [4,] 1 1 1 1 1 1 1 [5,] 1 1 1 1 1 1 1 [,8] [,9] [,10] [1,] 9 14 13 [2,] 8 2 3 [3,] 1 2 2 [4,] 1 1 1 [5,] 1 1 1 > HTH Robin On 30 Aug 2006, at 14:49, Doran, Harold wrote:> Dear list > > Suppose I have the following vector: > > x <- c(3,4,2,5,6) > > Obviously, this sums to 20. Now, I want to have a second vector, > call it > x2, that sums to x where 5 <= x <= 20, but there are constraints. > > 1) The new vector must be same length as x > 2) No element of the new vector can be 0 > 3) Element x2[i] of the new vector cannot be larger than element x > [i] of > the original vector > 4) Ordering is not important > > The following would be an example of what I would want if the user > wanted the vector x2 to sum to 19 > > x2 <- c(2,4,2,5,6) > > Or, because ordering is not important, this is acceptable > > x2 <- c(3,3,2,5,6) > > Whereas this would not be appropriate > > x3 <- c(4, 2,2,5,6) > > Because element x3[1] is larger than x[1] even though it sums to 19. > > Ideally, the function would take as input the original vector, x, and > the number that the new vector would sum to. In this example, the > vector > could sum to any number 5 through 20. > > For example, > > myFun <- function(x, sumto) ... details ... > > Is there a preexisiting function that would already do this? I have > spent too much (unsuccessful) time trying to write a function of my > own > but can't seem to get this to work properly. > > Any hints would be greatly appreciated. > > Harold > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.-- Robin Hankin Uncertainty Analyst National Oceanography Centre, Southampton European Way, Southampton SO14 3ZH, UK tel 023-8059-7743
On 8/30/2006 9:49 AM, Doran, Harold wrote:> Dear list > > Suppose I have the following vector: > > x <- c(3,4,2,5,6) > > Obviously, this sums to 20. Now, I want to have a second vector, call it > x2, that sums to x where 5 <= x <= 20, but there are constraints. > > 1) The new vector must be same length as x > 2) No element of the new vector can be 0 > 3) Element x2[i] of the new vector cannot be larger than element x[i] of > the original vector > 4) Ordering is not important > > The following would be an example of what I would want if the user > wanted the vector x2 to sum to 19 > > x2 <- c(2,4,2,5,6) > > Or, because ordering is not important, this is acceptable > > x2 <- c(3,3,2,5,6) > > Whereas this would not be appropriate > > x3 <- c(4, 2,2,5,6) > > Because element x3[1] is larger than x[1] even though it sums to 19.I don't think it's really clear what you mean by "ordering is not important". Would x2 <- c(6,5,2,4,2) be acceptable (a re-ordering of your first two examples), even though x2[1] > x1[1]? It's also not clear what result you want in the usual case where there are multiple possible answers. Do you want a randomly chosen one (from what distribution?), or would any value satisfying the constraints be okay? (The latter would be easiest: just start with x1, and decrement entries until the desired sum is achieved. Whether a random value is easy or not really depends on the desired distribution.) Do entries need to be integer valued?> > Ideally, the function would take as input the original vector, x, and > the number that the new vector would sum to. In this example, the vector > could sum to any number 5 through 20. > > For example, > > myFun <- function(x, sumto) ... details ... > > Is there a preexisiting function that would already do this? I have > spent too much (unsuccessful) time trying to write a function of my own > but can't seem to get this to work properly.I doubt it, because this doesn't look like a standard problem. Duncan Murdoch> > Any hints would be greatly appreciated. > > Harold > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
I think I've got it now. If I understand your question, try: > x <- do.call("cbind",lapply(5:7,function(i){restrictedparts(i, 5,include.zero=FALSE)})) > acceptable <- function(x){all(x<=c(3,4,5,2,6))} > x[,apply(x,2,acceptable)] [,1] [,2] [,3] [,4] [1,] 1 2 3 2 [2,] 1 1 1 2 [3,] 1 1 1 1 [4,] 1 1 1 1 [5,] 1 1 1 1 > rksh On 30 Aug 2006, at 14:49, Doran, Harold wrote:> Dear list > > Suppose I have the following vector: > > x <- c(3,4,2,5,6) > > Obviously, this sums to 20. Now, I want to have a second vector, > call it > x2, that sums to x where 5 <= x <= 20, but there are constraints. > > 1) The new vector must be same length as x > 2) No element of the new vector can be 0 > 3) Element x2[i] of the new vector cannot be larger than element x > [i] of > the original vector > 4) Ordering is not important > > The following would be an example of what I would want if the user > wanted the vector x2 to sum to 19 > > x2 <- c(2,4,2,5,6) > > Or, because ordering is not important, this is acceptable > > x2 <- c(3,3,2,5,6) > > Whereas this would not be appropriate > > x3 <- c(4, 2,2,5,6) > > Because element x3[1] is larger than x[1] even though it sums to 19. > > Ideally, the function would take as input the original vector, x, and > the number that the new vector would sum to. In this example, the > vector > could sum to any number 5 through 20. > > For example, > > myFun <- function(x, sumto) ... details ... > > Is there a preexisiting function that would already do this? I have > spent too much (unsuccessful) time trying to write a function of my > own > but can't seem to get this to work properly. > > Any hints would be greatly appreciated. > > Harold > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.-- Robin Hankin Uncertainty Analyst National Oceanography Centre, Southampton European Way, Southampton SO14 3ZH, UK tel 023-8059-7743
Hi Duncan Here is a bit more detail, this is a bit tough to explain, sorry for not being clear. Ordering is not important because the vector I am creating is used as a sufficient statistic in an optimization routine to get some MLEs. So, any combination of the vector that sums to X is OK. But, the condition that x2[i] <= x[i] must be maintained. So, the example below would not work because x2[1] > x[1] as you note below.> I don't think it's really clear what you mean by "ordering is > not important". Would > > x2 <- c(6,5,2,4,2) > be acceptable (a re-ordering of your first two examples), > even though x2[1] > x1[1]?To be concrete, the following is the optimization function. This is a psychometric problem where the goal is to get the MLE for a test taker conditional on their response pattern (i.e., number of points on the test) and the item parameters. pcm.max3 <- function(score, d){ pcm <- function(theta, d, score) exp(sum(theta-d[1:score]))/sum(exp(cumsum(theta-d))) opt <- function(theta) -sum(log(mapply(pcm, d, theta = theta, scorescore ))) start_val <- log(sum(score-1)/(length(score-1)/sum(score-1))) out <- optim(start_val, opt, method = "BFGS", hessian = TRUE) cat('theta is about', round(out$par, 2), ', se', 1/sqrt(out$hes),'\n') } Suppose we have a three item test. I store the item parameters in a list as items <- list(c(0,.5,1), c(0,1), c(0, -1, .5, 1)) We can get the total possible number correct as (x <- sapply(items, length)) [1] 3 2 4 But, you cannot actually get the MLE for this because the likelihood is unbounded in this case. So, let's say the student scored in the following categories for each item: x2 <- c(3,1,4) By x2[i] <= x[i], I mean that there are 3 possible categories for item 1 above. So, a student can only score in categories 1,2 or 3. He cannot score in category 4. This is why the condition that x2[i] <= x[i] is critical. But, because total score is a sufficient statistic, (i.e., "ordering is not important") we could either vector in the function pcm. x3 <- c(3,2,3) Using the function pcm.max3(x2, items) pcm.max3(x3, items) Gives the same MLE. But, the vector X_bad <- c(4,1,3) Would not work. You can see that the elements of this vector actually serve as indices denoting which category a test taker scored in for each item in the list "items" I hope this is helpful and appreciate your time. Harold> > > > ______________________________________________ > > R-help at stat.math.ethz.ch mailing list > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide > > http://www.R-project.org/posting-guide.html > > and provide commented, minimal, self-contained, reproducible code. > >