I'm a new (~1 day old) R user. I'm trying to generate all 216 outcomes of three throws of a six-sided die. The point is to then apply some function to each triplet (say, maximum face value). This is what I've come up with:
mat <- matrix(numeric(0), ncol=3)
for (i in 1:6) {
for (j in 1:6) {
for (k in 1:6) {
mat <- rbind(mat, c(i, j, k))
}
}
}
# find maximum of each outcome
apply(mat, 1, max)
Is there a better and more concise way to do this with R?
I would've liked to use outer
this way:
outer(1:6, outer(1:6, 1:6, max), max)
but it fails with the error
Error in outer(1:6, 1:6, max) : dims [product 36] do not match the length of object [1]
In linear algebra, the outer product of two coordinate vectors is a matrix. If the two vectors have dimensions n and m, then their outer product is an n × m matrix.
To get the Outer product of two arrays, use the numpy. outer() method in Python. The 1st parameter a is the first input vector. Input is flattened if not already 1-dimensional.
outer() function compute the outer product of two vectors. Parameters : a : [array_like] First input vector.
Definition: Inner and Outer Product. If u and v are column vectors with the same size, then uT v is the inner product of u and v; if u and v are column vectors of any size, then uvT is the outer product of u and v.
We can use expand.grid
to create the combinations in a data.frame
, convert to matrix
and get the maximum value of each row by rowMaxs
from library(matrixStats)
.
library(matrixStats)
rowMaxs(as.matrix(expand.grid(rep(list(1:6),3))))
#[1] 1 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 2
#[38] 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 3 3
#[75] 3 4 5 6 3 3 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 4 4 4
#[112] 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 5 5 5 5
#[149] 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6
#[186] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
Or we can use pmax
with expand.grid
do.call(pmax, expand.grid(rep(list(1:6),3)))
Or as suggested by @Ben Bolker, we can also use apply
with MARGIN=1
apply(expand.grid(rep(list(1:6),3)),1,max)
Another option is outer
with pmax
.
c(outer(1:6, outer(1:6, 1:6, FUN=pmax), FUN= pmax))
#[1] 1 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 2
#[38] 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 3 3
#[75] 3 4 5 6 3 3 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 4 4 4
#[112] 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 5 5 5 5
#[149] 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6
#[186] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
Or outer
with Vectorize
d max
f1 <- function(x,y) max(x,y)
c(outer(1:6, outer(1:6, 1:6, Vectorize(f1)), Vectorize(f1)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With