Removing columns from a matrix in R when any value is greater than, equal to, or less than a threshold

I'm playing with dummy cubes - two of them - and I want to generate all the permutations that can be added up to a certain value, like "9". So we have {3.6}, {4.5}, {5.4} and {6.3}. But I want to expand on this and I need some code.

If I wanted to know the permutations adding instead of "6" this could do:

library(partitions)
compositions(6, m = 2)

[1,] 6 5 4 3 2 1 0
[2,] 0 1 2 3 4 5 6

      

This will give me almost what I need - we roll two dice, so there won't be any zeros ... I'll come back to this later ...

Unfortunately, when you go above "6", you start to get songs with numbers greater than "6" that are not found on the sides of the cube. Therefore, I have to exclude from the matrix returned by compositions()

ANY columns with values โ€‹โ€‹greater than "6". And yes, any columns with zeros as well.

Can you help, perhaps by applying all

either or any

or a subset with parentheses, to come up with a short, elegant way to eliminate unwanted columns in the case of "9" (or other> 6 examples):

compositions(9,2)

[1,] 9 8 7 6 5 4 3 2 1 0
[2,] 0 1 2 3 4 5 6 7 8 9

      

+3


source to share


4 answers


You can simply use the apply function like below:

ans <- compositions(9, m = 2)
ans[,apply(ans,2,function(x) all(x<=6))]

      

with output:

     [,1] [,2] [,3] [,4]
[1,]    6    5    4    3
[2,]    3    4    5    6

      


Alternatively, you can use dplyr

, which will look cleaner and may be more intuitive:

library(dplyr)
expand.grid(d1=1:6, d2=1:6) %>% filter(d1+d2 == 9)

      



output:

  d1 d2
1  6  3
2  5  4
3  4  5
4  3  6

      

Or using ans

from above:

data.frame(as.matrix(t(ans))) %>% filter(X1 <= 6 & X2 <= 6)

      

Output:

  X1 X2
1  6  3
2  5  4
3  4  5
4  3  6

      

+1


source


Building the correct set is cleaner than filtering the wrong set (as requested by the OP):

twodice <- function(x){d1 <- if (x>6) 6:(x-6) else 1:(x-1); rbind(d1,rev(d1))}

      



Examples:

> twodice(4)
   [,1] [,2] [,3]
d1    1    2    3
      3    2    1
> twodice(9)
   [,1] [,2] [,3] [,4]
d1    6    5    4    3
      3    4    5    6

      

+2


source


I first check if any value in the columns has any value greater than the threshold, and then see if there are any double FALSEs.

above.th <- apply(
    apply(x, MARGIN = 2, FUN = function(m) m > 6),
    MARGIN = 2,
    any)
x[, !above.th]

And I get this result

     [,1] [,2] [,3] [,4]
[1,]    6    5    4    3
[2,]    3    4    5    6

      

0


source


@chappers has a very nice, short solution and I'll follow his answer. At about the same time I got the following, which seems to work well and is very similar:

a <- compositions(9,2)
a[,which(!apply(a, 2, function(x){any(x > 6) + any(x == 0)}))]

     [,1] [,2] [,3] [,4]
[1,]    6    5    4    3
[2,]    3    4    5    6

      

0


source







All Articles