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
source to share
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
source to share
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
source to share
@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
source to share