Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find out how many rows of a matrix satisfy a rather complicated criterion (in R)?

As an example, here is a way to get a matrix of all possible outcomes of rolling 4 (fair) dice.

z <- as.matrix(expand.grid(c(1:6),c(1:6),c(1:6),c(1:6)))

As you may already have understood, I'm trying to work out a question that was closed, though, in my opinion, it's a challenging one. I used counting techniques to solve it (I mean by hand) and I finaly arrived to a number of outcomes, with a sum of subset being 5, equal to 1083 out of 1296. That result is consistent with the answers provided to that question, before it was closed. I was wondering how could that subset of outcomes (say z1, where dim(z1) = [1083,4] ) be generated using R. Do you have any ideas?

Thank you.

like image 858
Brani Avatar asked May 22 '10 20:05

Brani


2 Answers

sum(apply(z, 1, function(x) 5 %in% unlist(sapply(1:4, function(i) combn(x, i, sum)))))
like image 124
Jonathan Chang Avatar answered Sep 22 '22 01:09

Jonathan Chang


This works for me:

require(combinat)

# Returns the sums of all the possible subsets for a single combination
comb <- function(values)
    {
    sums <- NULL

    # Sum each combination of 1,2,... n-1 dice
    for (i in 1:(length(values)-1))
        {
        c <- combn(values, i)
        sums <- c(sums, colSums(c))
        }

    # Also sum all the dice
    sums <- c(sums, sum(values))

    comb <- sums
    }

# Returns TRUE if the array contains a certain value
hasVal <- function(values, n)
    {
    hasVal <- (length(which(values == n)) > 0)
    }

dice <- as.matrix(expand.grid(1:6, 1:6, 1:6, 1:6))
theSum <- 5

# Get the sums of all the subsets for each line
sums <- apply(z, 1, comb)
# See which columns of sums contain 5 
has5 <- apply(sums, 2, hasVal, theSum)
# Now count them :)
print(paste(length(which(has5 == TRUE)), " combinations over ", 
        length(has5), " have a subset that sums to ", theSum))

And outputs:

[1] "1083 combinations over 1296 have a subset that sums to 5"

like image 36
nico Avatar answered Sep 22 '22 01:09

nico