I have an R loop that has been giving me error. Here are the dimensions of the matrices..
> dim(A)
[1] 2 2
> dim(backward)
[1] 6848 2
I am trying to run this loop and get the following error:
for (i in t:1){
backward[i,]=A%*%t(backward[i,])}
Error in A %*% t(backward[i, ]) : non-conformable arguments
Where t equals 6848. Thanks for your time.
EDIT with bgoldst code:
> A
[,1] [,2]
[1,] 0.8 0.2
[2,] 0.2 0.8
> backward <- matrix(1:(t*2),t,2);
> dim(backward)
[1] 6848 2
> for (i in t:1) backward[i,] <- A%*%t(backward[i,,drop=F]);
Error in A %*% t(backward[i, , drop = F]) : non-conformable arguments
I'm guessing that your expectation of
backward[i,]
is that it will return a 1x2 matrix, which you would be able to use as the operand of a matrix multiplication. This is incorrect. In R, when you specify a single index within a dimension of a matrix, then by default, R will "drop" that dimension. In the case of the above piece of code, the row dimension is dropped, and you end up with a vector, whose contents are taken from all columns along the indexed row. A vector is not a valid operand to a matrix multiplication.
You can solve this problem by providing the drop argument to the [ operation:
A <- matrix(1:(2*2),2,2);
backward <- matrix(1:(6848*2),6848,2);
t <- nrow(backward); for (i in t:1) backward[i,] <- A%*%t(backward[i,,drop=F]); ## no error
Here's a demo of the effect of drop=F:
backward[1,]
## [1] 20548 27398
backward[1,,drop=F]
## [,1] [,2]
## [1,] 20548 27398
See ?`[` for more info.
Here's a solution that doesn't depend on the drop=F argument:
for (i in t:1) backward[i,] <- A%*%t(matrix(backward[i,],1));
Related
I need to find the optimal weight (a) to minimize sum of squared errors. I use this as an example as I'll have a more complex problem to work on which requires the use of some other optimization packages but lm. I receive warnings() saying that "In a * y. Recycling array of length 1 in array-vector arithmetic is deprecated. Use c() or as.vector() instead." I tried as.vector(a * y), a[1] * y, a * as.vector(y) but nothing works.
What should I do to get rid of this message?
install.packages("NlcOptim")
library(NlcOptim)
x <- c(1:4)
y <- c(2,4,6,8)
objfun <- function(a) {
return(sum((x-a*y)^2))
}
x0 <- 1
solnl(x0,objfun = objfun)
Here is the error message that I see after typing warnings():
1: In a * y :
Recycling array of length 1 in array-vector arithmetic is deprecated.
Use c() or as.vector() instead.
Actually I would suggest to do nothing about it. R simply does not like to adding one dimensional arrays to numeric vectors.
x <- array(1, dim = 1);
x + c(1,1)
[1] 2 2
Warning message:
In x + c(1, 1) :
Recycling array of length 1 in array-vector arithmetic is deprecated.
Use c() or as.vector() instead.
As you can see, the result is correct, so you are pretty safe to ignore that warning.
A bit late, but found your question when I tumbled into the same warning message. In your case, I think you need to treat a as a vector with c(a) or as.vector(a) inside your function objfun. (So you almost got it with your tries as.vector(a * y), a[1] * y and a * as.vector(y)).
Thus:
install.packages("NlcOptim")
library(NlcOptim)
x <- c(1:4)
y <- c(2,4,6,8)
objfun <- function(a) {
return(sum((x-c(a)*y)^2))
}
x0 <- 1
solnl(x0,objfun = objfun)
Running this code we obtain
$par
[,1]
[1,] 0.5
$fn
[1] 5.913821e-15
$counts
nfval ngval
[1,] 13 3
$lambda
$lambda$lower
[,1]
[1,] 0
$lambda$upper
[,1]
[1,] 0
$grad
[,1]
[1,] 1.033147e-07
$hessian
[,1]
[1,] 240
Warning message:
In cbind(LAMBDA, 0.5 * (LAMBDA + LAMBDA_old)) :
number of rows of result is not a multiple of vector length (arg 1)
I don't know what the last warning means, but it is into the package you are using.
This is confusing indeed, but what you really need to do is, in fact, use as.numeric, like this:
return(sum((x-as.numeric(a)*y)^2))
doing R's job of interpreting a 1x1 array as a scalar. Not sure how as.vector() or c() would have ever been helpful.
I write code manually of QR decomposition using Gram-Schmidt orthogonalization:
A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0),c(2,3,4))
gsm<-function(X){
m<-ncol(X)
n<-nrow(X)
# initialize Q and R
q<-matrix(0,m,n)
r<-matrix(0,n,n)
v<-matrix(0,m,n)
# initialize V
v[,1]<-X[,1]
q[,1]<-v[,1]/sqrt(sum(v[,1]^2))
r[1,1]<-t(X[,1])%*%q[,1]
for (i in 2:n){
dv<-0
for (j in 1:(i-1)) {
r[j,i]<-t(X[,i])%*%q[,j]
dv<-dv+r[j,i]*q[,j]
}
v[,i]<-X[,i]-dv
q[,i]<-v[,i]/sqrt(t(v[,i])%*%v[,i])
r[i,i]<-t(X[,i])%*%q[,i]
}
qrreport<-list("Q"=q,"R"=r)
return(qrreport)
}
gsm(A)
However, the code doesn't work and gives me the error:
Error in v[, 1] <- X[, 1] : number of items to replace is not a multiple of replacement length
And when I replace A with a 3*3 matrix: A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0)) and operate the function again, R throws a new error to me as:
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
$ Q
[,1] [,2] [,3]
[1,] 0.1097643 0.89011215 -0.4423259
[2,] -0.1097643 0.45314800 0.8846517
[3,] 0.9878783 -0.04855157 0.1474420
$R
[,1] [,2] [,3]
[1,] 18.22087 0.1097643 -0.1097643
[2,] 0.00000 2.2333723 1.7964082
[3,] 0.00000 0.0000000 1.3269776
I am very confused where I make mistakes and hope someone could help me debug.
Your A matrix has 3 rows and 4 columns, so in gsm() m is 4 and n is 3. That means v has 4 rows and 3 columns, whereas X, which is really A, only has 3 rows. When v[, 1] <- X[, 1] tries to put the 1st column of X into the first
column of A, you get the error message you saw.
To debug things like this in RStudio, set a breakpoint on the line v[, 1] <- X[, 1] that caused the error, and look at the different items in the expression before executing it. If you're not using RStudio, you can still set a breakpoint there using the setBreakpoint function, but it's a lot more work.
I am following some code using a matrix transformation with an input of type num:
> input
1 101.3862407 63.8025351
2 -39.2936491 0.3279252
3 -2.5526003 1.8761791
4 36.1441720 45.3625071
....
And a transformation matrix:
transfmatrix <- matrix(c(0.9,-0.1,0.1,0.9),nrow=2)
> transfmatrix
[,1] [,2]
[1,] 0.9 0.1
[2,] -0.1 0.9
I can then do a data transformation using:
# transformation
result <-input%*%transfmatrix
This works fine, but I would like "input" to be a raster file.
Is it possible to apply a similar transformation to raster layers? I tried the following:
library(raster)
r <- raster(ncol=40, nrow=20)
r[] <- rnorm(n=ncell(r))
test1<-stack(r,r*2)
test2 <- test1%*%transfmatrix
but received an error:
Error in test1 %*% transf.m :
requires numeric/complex matrix/vector arguments
You need to make a 2-column matrix from your data to multiply by the 2x2 matrix. Perhaps this:
> z = as.matrix(test1) %*% transf.m
> dim(z)
[1] 800 2
That makes an 800x2 matrix from the 800 cells of test1.
If you want a raster stack with the values, then, overwriting test1, do:
> test1[[1]][]=z[,1]
> test1[[2]][]=z[,2]
I am trying to multiply matrices in R. However, I am unable to do so without error. The multiplication of the dimensions seem right, but not sure what it could be. Here is some background on my data and what my loop is. Thanks for the help.
t
# [1] 6848
dim(A)
# [1] 2 2
dim(backward)
# [1] 6848 2
dim(B)
# [1] 6848 2
is.matrix(A)
# [1] TRUE
is.matrix(backward)
# [1] TRUE
is.matrix(B)
# [1] TRUE
for (i in (t-1):1){ #FIXXXXX
backward[i,] = t(A%*%(t(backward[i+1,])))*B[i+1,]
}
Error in A %*% (t(backward[i + 1, ])) : non-conformable arguments
By default, selecting a single row or column from a matrix results in a vector. Add drop=FALSE to your subsetting expression to keep this from happening.
t(A %*% t(backward[i+1, , drop=FALSE])) * B[i+1, , drop=FALSE]
And by the way, it would probably be a good idea to rename your t variable to something else, as t is also the transpose function.
Suppose I have a function that takes an argument x of dimension 1 or 2. I'd like to do something like
x[1, i]
regardless of whether I got a vector or a matrix (or a table of one variable, or two).
For example:
x = 1:5
x[1,2] # this won't work...
Of course I can check to see which class was given as an argument, or force the argument to be a matrix, but I'd rather not do that. In Matlab, for example, vectors are matrices with all but one dimension of size 1 (and can be treated as either row or column, etc.). This makes code nice and regular.
Also, does anyone have an idea why in R vectors (or in general one dimensional objects) aren't special cases of matrices (or multidimensional objects)?
Thanks
In R, it is the other way round; matrices are vectors. The matrix-like behaviour comes from some extra attributes on top of the atomic vector part of the object.
To get the behaviour you want, you'd need to make the vector be a matrix, by setting dimensions on the vector using dim() or explicit coercion.
> vm <- 1:5
> dim(vm) <- c(1,5)
> vm
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
> class(vm)
[1] "matrix"
Next you'll need to maintain the dimensions when subsetting; by default R will drop empty dimensions, which in the case of vm above is the row dimension. You do that using drop = FALSE in the call to '['(). The behaviour by default is drop = TRUE:
> vm[, 2:4]
[1] 2 3 4
> vm[, 2:4, drop = FALSE]
[,1] [,2] [,3]
[1,] 2 3 4
You could add a class to your matrices and write methods for [ for that class where the argument drop is set to FALSE by default
class(vm) <- c("foo", class(vm))
`[.foo` <- function(x, i, j, ..., drop = FALSE) {
clx <- class(x)
class(x) <- clx[clx != "foo"]
x[i, j, ..., drop = drop]
}
which in use gives:
> vm[, 2:4]
[,1] [,2] [,3]
[1,] 2 3 4
i.e. maintains the empty dimension.
Making this fool-proof and pervasive will require a lot more effort but the above will get you started.