Filling matrix in R without for loops - r

I am a beginner in R and i know the way i have done is wrong and slow. I would like to fill a matrix and i need to compute each term. I have tried two for loops, here is the code. Do you know a better way to do it?
KernelGaussianMatrix <- function(x,delta){
Mat = matrix(0,nrow=length(x),ncol=length(x))
for (i in 1:length(x)){
for (j in 1:length(x)){
Mat[i,j] = KernelGaussian(x[i],x[j],delta)
}
}
return(Mat)
}
Thx

you want to use the function outer as in:
Mat <- outer(x,x,KernelGaussian,delta)
note that any arguments after the third argument in outer are provided as additional arguments to the function provided as the third argument to outer

If a for loop is required to generate the values than your method is fine.
If the values are already in an array values you can try mat = matrix(values, nrow=n, ncol=p) or something similar.

Related

How to use lapply with a condition in R to fit only one element each time

Suppose I have two vectors. Suppose further that I would like my function takes only one values of each vector and return me the output. Then, I would like another function to check the values of each run. If the output of the previous run is smaller than the new one. Then, I would like my function to stop and return me all the previous values. My original function is very complicated (estimation models). Hence, I try to provide an example to explain my idea.
Suppose that I have these two vectors:
set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)
Then, I would like to write a function which only takes one values of each vector and multiplied them. Then, return me the output. Then, I would like the function to check if the previous multiplication is smaller than the new one or not. If yes, then stop and return me all the previous multiplication.
I tried this:However, this functions takes all the values at once and return me a list of the multiplication. I was thinking about using lapply, to fit one element at a time but I do not know how to work with the conditions.
myfun <- function(x, y, n){
multi <- list()
for ( i in 1:n){
multi[[i]] <- x[[i]]*y[[i]]
}
return(multi)
}
myfun(x,y,10)
Here is another try
x <- rnorm(1:20)
y <- rnorm(1:20)
myfun <- function(x, y){
multi <- x*y
return(multi)
}
This is the first function. I would like to run it element by element. Each time, I would like it to returns me only one multiplication result. Then, another function (wrapper function) check the result. It the second output of the first function (multiplication function) is larger than the first one, then stop, otherwise keep going.
I would like to write a function which only takes one values of each vector and multiplied them. Then, return me the output. Then, I would like the function to check if the previous multiplication is smaller than the new one or not.
I would like the multiplication in a separate function. Then, I would like to check its output. So, I should have a warper function.
You can apply a for loop with a stopping condition, similar to what you have already:
# example input
set.seed(123)
x <- rnorm(1:20)
y <- rnorm(1:20)
# example function
f = function(xi, yi) xi*yi
# wrapper
stopifnot(length(x) == length(y))
res = vector(length(x), mode="list")
for (i in seq_along(x)){
res[[i]] = f(x[[i]], y[[i]])
if (i > 1L && res[[i]] > res[[i-1L]]) break
}
res[seq_len(i)]
Comments:
It is better to predefine the max length res might need (here, length(x)), rather than expanding it in the loop.
For this function (multiplication), there is no good reason to proceed elementwise. R's multiplication function is vectorized and fast.
You don't need to use a list-class output for this function, since it is returning doubles; res = double(length(x)) should also work.
You don't need to use list-style accessors for x, y and res unless lists are involved; res[i] = f(x[i], y[i]) should work, etc.

Matrix of expected values from matrix of observed using a loop

I am trying to figure out how to use a for loop to create a matrix of expected values. it should be able to handle a matrix of any size. This is all I've been able to come up with so far.
for(i in 1:obsv){
for(j in 1:obsv){
obsv[i,j]<-(sum(obsv[i,])*sum(obsv[,j]))/sum(obsv)
}
}
##obsv is the name of the matrix of observed values
Your loop is obviously wrong, see below. The main error was that you need to loop through 1:nrow(obsv) and 1:ncol(obsv), not like you are doing it.
I will use a fake matrix, since you haven't posted an example dataset.
obsv <- matrix(1:25, ncol = 5)
obsv2 <- obsv # modify a copy
for(i in 1:nrow(obsv)){
for(j in 1:ncol(obsv)){
obsv2[i, j] <- sum(obsv[i, ])*sum(obsv[, j])/sum(obsv)
}
}
Now, the above code can be greatly simplified. A one-liner will do it.
obsv3 <- rowSums(obsv) %*% t(colSums(obsv))/sum(obsv)
identical(obsv2, obsv3)
#[1] TRUE

Which function inside a loop is more efficient (ncol/nrow() or dim())

In an exercise attempt I am trying to create a multiplication table using a for loop. I am new to programming and R is my first language that I learn, so I would like to know which functions inside loops are faster and more efficient. For now, I am not using methods of the apply family because I think that understanding of basic functions like the loops is important.
Here are two ways that I use to create a multiplicaton table:
Using dim() function:
mtx <- matrix(nrow=10, ncol=10)
for(i in 1:dim(mtx)[1]){
for(j in 1:dim(mtx)[2]){
mtx[i,j] <- i*j
}
}
Using ncol/nrow() function:
mtx <- matrix(nrow=10, ncol=10)
for(i in 1:ncol(mtx)){
for(j in 1:nrow(mtx)){
mtx[i,j] <- i*j
}
}
Which way is more efficient and generaly better to use?
Thank you
If you use the functions like you do in your example, the difference is really neglectable. This is because the functions get called only once per loop definition (and not every loop iteration!)
I would definitely prefer ncol/nrow because its much easier too read than dim(x)[1].
That being said, if you just go for the timings, the dim function is faster than ncol/nrow. If you look at the source code, you can see that ncol is implemented as
function (x)
dim(x)[2L]
which means that ncol calls dim and is therefore marginally slower.
If you really want to save some speed with big matrices I would suggest to create the loop vectors beforehand like this:
rows <- 1:nrow(mtx)
cols <- 1:ncols(mtx)
for (i in rows) {
for (j in cols) {
mtx[i, j] <- i * j
}
}

How to square matrix elements in R using loops and apply function

I have a 3x3 matrix that I have made in R. I am being asking to square all the numbers in the matrix. First using loops and then using the apply function. I have done the following already.
myMatrix = matrix ( c(1,2,3,4,5,6,7,8,9), nrow=3, ncol=3)
So that gives me my matrix. Then I used this to square them
myMatrix * myMatrix ##don't know how to make a loop to do this
And finally my attempt to use the apply() function to do the same thing
apply(myMatrix, c(1,2), exp) ##this gave me numbers that didnt look correct
Any help in the right direction would be very nice.
Thanks
The accepted answer is highly inefficient; Instead one should realize that the "^" operator works in an element wise fashion and use:
sqrdMtx <- myMatrix^2
The "^" operator is not matrix power when its arguments are matrices. For that you need matpow in pkg:expm.
As some comments mentioned, these are not the best approach to squaring a matrix. But since you asked...
Using a loop:
myMatrix = matrix ( c(1,2,3,4,5,6,7,8,9), nrow=3, ncol=3)
# empty matrix for the results
squaredMatrix = matrix(nrow=3, ncol=3)
for(i in 1:nrow(myMatrix)) {
for(j in 1:ncol(myMatrix)) {
squaredMatrix[i,j] = myMatrix[i,j]^2
}
}
Edit:
As noted in a comment below, you can also use a single loop:
squaredMatrix = matrix(nrow=3, ncol=3)
for (i in 1:length(myMatrix)) {
squaredMatrix[i] <- myMatrix[i]^2
}
Using the apply function:
squaredMatrix = apply(myMatrix, c(1,2), function(x) x^2)

How to use extract function in a for loop?

I am using the extract function in a loop. See below.
for (i in 1:length(list_shp_Tanzania)){
LU_Mod2000<- extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj)
}
Where maj function is:
maj <- function(x){
y <- as.numeric(names(which.max(table(x))))
return(y)
}
I was expecting to get i outputs, but I get only one output once the loop is done. Somebody knows what I am doing wrong. Thanks.
One solution in this kind of situation is to create a list and then assign the result of each iteration to the corresponding element of the list:
LU_Mod2000 <- vector("list", length(list_shp_Tanzania))
for (i in 1:length(list_shp_Tanzania)){
LU_Mod2000[[i]] <- extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj)
}
Do not do
LU_Mod2000 <- c(LU_Mod2000, extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj))
inside the loop. This will create unnecessary copies and will take long to run. Use the list method, and after the loop, convert the list of results to the desired format (usually using do.call(LU_Mod2000, <some function>))
Alternatively, you could substitute the for loop with lapply, which is what many people seem to prefer
LU_Mod2000 <- lapply(list_shp_Tanzania, function(z) extract(x=rc_Mod2000_LC, y=z, fun=maj))

Resources