Multiply permutations of two vectors in R
Use outer(A,B,'*')
which will return a matrix
x<-c(1:4)
y<-c(10:14)
outer(x,y,'*')
returns
[,1] [,2] [,3] [,4] [,5]
[1,] 10 11 12 13 14
[2,] 20 22 24 26 28
[3,] 30 33 36 39 42
[4,] 40 44 48 52 56
and if you want the result in a list you then can do
z<-outer(x,y,'*')
z.list<-as.list(t(z))
head(z.list)
returns
[[1]]
[1] 10
[[2]]
[1] 11
[[3]]
[1] 12
[[4]]
[1] 13
[[5]]
[1] 14
[[6]]
[1] 20
which is x1*y1, x1*y2, x1* y3, x1*y4, x2*y1 ,... (if you want x1*y1, x2*y1, ... replace t(z)
by z
)
Multiplying vector combinations
You are probably looking for outer()
or it's alias binary operator %o%
:
> c(2,3,4) %o% c(1,2)
[,1] [,2]
[1,] 2 4
[2,] 3 6
[3,] 4 8
> outer(c(2,3,4), c(1,2))
[,1] [,2]
[1,] 2 4
[2,] 3 6
[3,] 4 8
In your case, outer()
offers the flexibility to specify a function that is applied to the combinations; %o%
only applies the *
multiplication function. For your example and data
mph <- function(d, rpm) {
cir <- pi * d
cir * rpm / 63360 * 60
}
> outer(c(20,26,29), c(150,350), FUN = mph)
[,1] [,2]
[1,] 8.924979 20.82495
[2,] 11.602473 27.07244
[3,] 12.941220 30.19618
Product between all combinations of a vector's elements
We can use combn
with anonymous function call
combn(vec, 2, FUN = function(x) x[1] * x[2])
#[1] 2 3 4 6 8 12
data
vec <- 1:4
multiplying each value in one vector to all values in a second vector and creating a results matrix
What you are looking for is outer
.
outer(x, y, FUN = "*")
If you want to use plus instead of multiplication you can change *
to ·+·
outer(x, y, FUN = "+")
How to calculate the product from combinations of several vectors in R?
The expand.grid
solution is OK, but in mathematics there is an elegant Kronecker product.
R has a function kronecker
, but it takes two vectors at a time, so we need Reduce
for a recursive application:
oo <- Reduce(kronecker, list(a, b, c, d))
Alternatively, use outer
(the workhorse of kronecker
):
rr <- Reduce(outer, list(a, b, c, d))
This is more user-friendly, as rr[i, j, u, v]
gives you a[i] * b[j] * c[u] * d[v]
.
Remark 1
Note that elements in oo
and rr
differ in order. Because for two vectors a
and b
:
kronecker(a, b) ## a[1] * b, a[2] * b ...
outer(a, b) ## a * b[1], a * b[2] ...
Thus the following use of kronecker
produces a result identical to rr
.
zz <- Reduce(kronecker, list(d, c, b, a))
dim(zz) <- c(length(a), length(b), length(c), length(d))
Remark 2
The method can be adapted to do a[i] + b[j] + c[u] + d[v]
, by replacing the default operation "*"
in outer
and kronecker
to "+"
. For example:
Reduce(function (x, y) outer(x, y, "+"), list(a, b, c, d))
Remark 3
johannes's answer can be improved. That row-wise application of apply
is a performance killer. We can do the following to get a result consistent with rr
.
xx <- Reduce("*", expand.grid(a, b, c, d))
dim(xx) <- c(length(a), length(b), length(c), length(d))
Pasting two vectors with combinations of all vectors' elements
You can use this, but there may be a simpler solution :
R> apply(expand.grid(vars, vis), 1, paste, collapse=".")
[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"
expand.grid
gives back a data.frame
which when used with apply
, apply
will convert it to a matrix
. This is just unnecessary (and inefficient on large data). outer
gives a matrix
and also takes function argument. It'll be much efficient on huge data as well.
Using outer
:
as.vector(outer(vars, vis, paste, sep="."))
# [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"
Combinations of multiple vectors in R
This is a useful case for storing the vectors in a list and using do.call()
to arrange for an appropriate function call for you. expand.grid()
is the standard function you want. But so you don't have to type out or name individual vectors, try:
> l <- list(a = 1:2, b = 3:4, c = 2:3)
> do.call(expand.grid, l)
a b c
1 1 3 2
2 2 3 2
3 1 4 2
4 2 4 2
5 1 3 3
6 2 3 3
7 1 4 3
8 2 4 3
However, for all my cleverness, it turns out that expand.grid()
accepts a list:
> expand.grid(l)
a b c
1 1 3 2
2 2 3 2
3 1 4 2
4 2 4 2
5 1 3 3
6 2 3 3
7 1 4 3
8 2 4 3
Related Topics
Compute All Fixed Window Averages with Dplyr and Rcpproll
Correlation Between Na Columns
R Cmd Check Note: Found No Calls To: 'R_Registerroutines', 'R_Usedynamicsymbols'
Comparison Between Dplyr::Do/Purrr::Map, What Advantages
Ggally::Ggpairs Plot Without Gridlines When Plotting Correlation Coefficient
Clip Values Between a Minimum and Maximum Allowed Value in R
How to Display a Busy Indicator in a Shiny App
Non-Linear Color Distribution Over the Range of Values in a Geom_Raster
Overlaying Two Graphs Using Ggplot2 in R
Adding Simple Legend to Plot in R
Merge Two Dataframes If Timestamp of X Is Within Time Interval of Y
Customizing the Sankey Chart to Cater Large Datasets
Jupyter-Client Has to Be Installed But "Jupyter Kernelspec --Version" Exited with Code 127
Piecewise Regression with R: Plotting the Segments
How to Plot a Subset of a Data Frame in R
How to Create a Continuous Density Heatmap of 2D Scatter Data in R
Dplyr 'Rename' Standard Evaluation Function Not Working as Expected