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)
Related
I have a rather simple problem and was wondering whether some of you guys know a very efficient (=fast) solution for this:
I have two matrices mat and arr and want to accomplish the following: Take every column of arr and substract it from mat. Then take the logarithm of one minus the absolute value of the difference. That's it. Right now, I'm using sapply (see below), but I'm pretty sure that it's possible to do it faster (maybe using sweep?)
Code:
mat <- matrix(.3, nrow=10, ncol = 4)
arr <- matrix(.1, nrow=10, ncol = 10000)
i <- ncol(arr)
result <- sapply(1:i, function(ii) (log(1-abs(mat-arr[,ii]))))
Thanks for any ideas!
We could replicate and then do a difference
result2 <- matrix(log(1- abs(rep(mat, ncol(arr)) -
rep(arr, ncol(mat)))), ncol = i)
identical(result, result2)
#[1] TRUE
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
My problem is basically this:
I have a list, L, where each element is a matrix of the same dimension. I need to multiply each matrix inside this list by its corresponding element in an outside vector h, and then sum all the matrices.
set.seed(101)
L <- replicate(3, matrix(rnorm(4), 2), simplify = FALSE)
h <- 2:4
# I need this
L[[1]] * h[1] + L[[2]] * h[2] + L[[3]] * h[3]
Given that I need to experiment with a different number of matrices, and I have a bunch of them, I've got to do it in a smart way. My idea was
L1 <- lapply(L, function(x) x * h[x])
L2 <- Reduce('+', L1)
Where "h[x]" would be indexing the vector h by the index of the matrix x inside the list L, so I would get
L1 = list(L[[1]] * h[1], L[[2]] * h[2], L[[3]] * h[3])
So, the question is, how to I get the index of an element in a list by using the element itself? Something like h[L[[m1]]] to get h[1].
Or, if you got any other way of solving my problem, how do I do it?
I think you're looking for mapply()/Map() (Map is slightly easier here because it doesn't try to simplify the results):
?Map:
‘Map’ applies a function to the corresponding elements of given vectors ... ‘Map’ is a simple wrapper to ‘mapply’ which does not attempt to simplify the result ...
?mapply:
‘mapply’ applies ‘FUN’ to the first elements of each ... argument, the second elements, the third elements, and so on
Set up example:
set.seed(101)
L <- replicate(3,matrix(rnorm(4),2),simplify=FALSE)
h <- 2:4
Do it:
Reduce("+",Map("*",L,h))
I might do
Reduce(
function(z,i) z + L[[i]]*h[i],
seq_along(L),
init = array(0, dim(L[[1]]))
)
Testing it on Ben's example data, I see the same result so I guess it works.
This is similar to an answer #eddi posted on my question about linear combos.
Using the foreach package, we can get the result as follows:
library(foreach)
foreach(i=seq_along(h), .combine="+") %do% {
L[[i]] * h[i]
}
The %do% loop runs through performing the element-wise multiplication, then the output summed using the .combine argument. This outputs the same result as Ben's Map-Reduce method.
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.
I have a 2D contingency table in R; it is a table object. I want to transform it into a new table by applying a function on each of its elements.
I looked at sapply, tapply, etc., but they are all aimed at summarising/aggregating the data. I've written my own mapping function which does this, which I reproduce below:
map.table = function(t,fn)
{
rows = dim(t)[1]
columns = dim(t)[2]
x = matrix(nrow=rows, ncol=columns)
rownames(x) = unlist(dimnames(bush.t)[1], use.names=FALSE)
colnames(x) = unlist(dimnames(bush.t)[2], use.names=FALSE)
for(row in seq(from=1, to=rows))
{
for(column in seq(from=1, to=columns))
{
x[row,column] = fn(t[row,column])
}
}
as.table(x)
}
This creates a matrix from scratch, fills up the dimension names, and the elements. Is there a better way of doing this? Is there an R function/package which already does this functionality?
You can probably just use apply:
set.seed(21)
x <- data.frame(a=sample(letters[1:5],20,TRUE),
b=sample(letters[1:5],20,TRUE))
y <- table(x)
z <- as.table(apply(y, 1:2, sqrt))
Why are you going to all this trouble? You should be able to do this:
fn(t)
(But also consider using a different name for your table, since t is a perfectly good base function name. At first I thought you were transposing your rows and columns.)
If your function does not work with vectors there is the possibility you can persuade it to do so. Try this:
vfn <- Vectorize(fn)
t2[] <- vfn(t)