Can I multiply vectors of different lengths? - r

v1 <- c(1,2)
v2 <- c(3,4,5,6)
Is there a way to multiply these two vectors such that the result is a vector dim(1,3)
such as (11,14,17)
This is analogous to all possible dim(1,2) multiplication combinations such as
(1,2) %x% t(3,4), (1,2) %x% t(4,5), (1,2) %x% t(5,6)
It seems so simple, have looked and no luck.

Create a 2-row matrix:
> rbind(v2[-length(v2)],v2[-1])
[,1] [,2] [,3]
[1,] 3 4 5
[2,] 4 5 6
Then it's just matrix multi:
> v1 %*% rbind(v2[-length(v2)],v2[-1])
[,1] [,2] [,3]
[1,] 11 14 17
and subset if you want a vector:
> (v1 %*% rbind(v2[-length(v2)],v2[-1]))[1,]
[1] 11 14 17

Use subsetting and cbind to create a matrix of your combinations, then apply across the rows of this with your multiplication.
apply(cbind(v2[-length(v2)],v2[-1]),1,function(x) v1%*%x)
[1] 11 14 17

Similar to James' answer, but maybe simpler:
sapply(1:(length(v2)-1), function(j) sum(v1*v2[j:j+1]))
Since you're only multiplying vectors (aka 1-by-N matrices :-) ), there's no need to dive into the matrix ops.

Another option:
na.omit(filter(v2, rev(v1)))
You could also use embed:
apply(embed(v2, 2), 1, FUN='%*%', rev(v1))

Related

Select one data point per row using indexing vector with negative values

Suppose you have a matrix a
a <- matrix(1:9, 3, 3)
a
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
and a vector b indicating which element of each row you want to extract. That is, the vector b indicates the column of the element, for instance:
b <- c(1, 3, 1)
If we want to extract the indicated data points, we can simply index each desired element like this:
a[cbind(1:nrow(a),b)]
[1] 1 8 3
I would like to do it with a negative index vector. That is, R should return a matrix where exactly one element per row is omitted (in this case, a 3x2 matrix). If I try it in a naive approach, R throws an error:
c = -b
a[cbind(1:nrow(a),c)]
Error in a[cbind(1:nrow(a), c)] :
negative values are not allowed in a matrix subscript
Thank you!
Not pretty, but you could do
b <- c(1, 3, 1) + 3 * 0:2
matrix(c(t(a))[-b], 3, 2, byrow = TRUE)
Maybe this is another naive approach. We loop over every row in the matrix and remove index specified in b.
t(sapply(seq_len(nrow(a)), function(x) a[x, -b[x]]))
# [,1] [,2]
#[1,] 4 7
#[2,] 2 5
#[3,] 6 9
Or using mapply with split
t(mapply(`[`, split(a, seq_len(nrow(a))), -b))

Avoid the for loop

I would like to compute the product between the each row of a matrix x with itself. And then sum the result of all these products. The result is a scalar. I make the following coda that works but is not efficient. Can someone help me to avoid the for loop?
for(i in 1:nrow(x){
resid2[i] <- t(x[i,])%*% x[i,]
}
V = sum(resid2)/
The solution is just the sum of squares of all elements of the matrix.
V = sum(x^2)
which can also be calculated via matrix multiplication as:
V = crossprod(as.vector(x))
The intermediate vector resid2 can be calculated as
resid2 = rowSums(x^2)
V = sum(resid2)
Here is an answer that swaps the for loop out for the apply family.
sum(apply(x, margin = 1, function(z) z%*%z))
The apply function takes the matrix x, margin = 1 means for each row (as opposed to margin = 2 which means each column). So, for each row in x run a function that multiplies that row by itself: function(z) z%*%z
If I understand you correctly, you don't need to loop at all. mat %*% mat should do it:
mat <- matrix(seq.int(9), nrow=3)
mat
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
mat %*% mat
## [,1] [,2] [,3]
## [1,] 30 66 102
## [2,] 36 81 126
## [3,] 42 96 150

Strange behavior of apply/ reverse function in R

I have a simple matrix:
mat = rbind(c(1:3),c(4:6),c(7:9))
mat
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 8 9
I want to now reverse the matrix row-wise. That is I want to obtain:
revMat
# [,1] [,2] [,3]
# [1,] 3 2 1
# [2,] 6 5 4
# [3,] 9 8 7
To do this I tried
apply(mat, 1, rev)
And the result was:
# [,1] [,2] [,3]
# [1,] 3 6 9
# [2,] 2 5 8
# [3,] 1 4 7
I find this to be extremely strange. It's like the rows are reversed and then the final matrix is transposed. I don't understand why. If I try simply, for instance,
apply(mat, 2, rev)
it gives me the expected reversal of each column
# [,1] [,2] [,3]
# [1,] 7 8 9
# [2,] 4 5 6
# [3,] 1 2 3
Therefore to obtain the final result I have to perform
t(apply(t(bg), 2, rev))
Thus obtaining the required matrix is NOT a problem for me, but I don't understand the "anomaly" in the behavior of apply/ reverse. Can anyone explain this to me?
Edit: To make clear the distinction, I already know how to do the reversal. I want to know WHY this happens. How to is clear from many earlier questions including
How to reverse a matrix in R?
apply always puts the result in the first dimension. See ?apply for more information. Assuming this input:
mat <- matrix(1:9, 3, byrow = TRUE)
here are some alternatives:
1) transpose
t(apply(mat, 1, rev))
2) avoid apply with indexing
mat[, 3:1]
3) iapply An idempotent apply was posted here:
https://stat.ethz.ch/pipermail/r-help/2006-January/086064.html
Using that we have:
iapply(mat, 1, rev)
There was also an idempotent apply, iapply, in version 0.8.0 of the reshape package (but not in the latest version of reshape): https://cran.r-project.org/src/contrib/Archive/reshape/
4) rollapply rollapply in the zoo package can be used:
library(zoo)
rollapply(mat, 1, rev, by.column = FALSE)
5) tapply The tapply expression here returns a list giving us the opportunity to put it together in the way we want -- in this case using rbind:
do.call("rbind", tapply(mat, row(mat), rev))
6) multiply by a reverse diagonal matrix Since rev is a linear operator it can be represented by a matrix:
mat %*% apply(diag(3), 1, rev)
or
mat %*% (row(mat) + col(mat) == 3+1)
If you look at the help for apply(), this is exactly the behavior you would expect:
Value
If each call to FUN returns a vector of length n, then apply returns
an array of dimension c(n, dim(X)[MARGIN]) if n > 1.
a nice option to do what you want is to use indexing:
mat[,ncol(mat):1]

Inconsistent vector operations in R?

I teach mathematics and programming (with R) at university and I am a big fan of a good and consistent notation. Please have a look at the following simple vector operations in R:
> v1 <- c(1,2,3)
> v2 <- c(4,5,6)
> v1 %*% v2
[,1]
[1,] 32
> t(v1) %*% v2
[,1]
[1,] 32
> v1 %*% t(v2)
[,1] [,2] [,3]
[1,] 4 5 6
[2,] 8 10 12
[3,] 12 15 18
> t(v1) %*% t(v2)
Error in t(v1) %*% t(v2) : non-conformable arguments
> v1 + v2
[1] 5 7 9
> v1 + t(v2)
[,1] [,2] [,3]
[1,] 5 7 9
> t(v1) + t(v2)
[,1] [,2] [,3]
[1,] 5 7 9
I think there are some inconsistencies here: Either I am missing something or R seems to be quite arbitrary with respect to what results you get when you either transpose a vector or not.
What is the underlying logic here (which seems to be completely different than Matlab by the way).
?%*% gives the logic:
Multiplies two matrices, if they are conformable. If one argument
is a vector, it will be promoted to either a row or column matrix
to make the two arguments conformable. If both are vectors it
will return the inner product (as a matrix).
If they're both vectors (first example), then you get the inner product. If you put a t( ) in there, the vector will get cast as a column matrix, and a vector is effectively a row matrix, so normable conformable rules apply.
Similarly, the help page for "+" says that it will cast the arguments to vectors - and gives some guidance on the 'shape' of the result.

Constructing a matrix as function of row and column

The situation is pretty straightforward. I want to create a matrix A of n rows and m columns, where the value for each element is given by a predetermined function f(i, j). What is the most elegant way to achieve this?
You can use outer:
outer(1:3,1:3,function(i,j) i^2+j)
[,1] [,2] [,3]
[1,] 2 3 4
[2,] 5 6 7
[3,] 10 11 12
It would help if you provided a reproducible example, but you could do something like this:
f <- function(i,j) i*j
m <- 4
n <- 2
out <- apply(expand.grid(1:m, 1:n), 1, function(x) f(x[1],x[2]))
dim(out) <- c(m,n)

Resources