I am a newbie to R, but avid to learn.
I have been trying endlessly to create a matrix with a variable element (in this case [2,2]). The variable element should take number 4 on the first run and 5 on the second (numbers).
This matrix would be multiplied by another matrix (N0) and produce a result matrix (resul).
Up so far, I have only been able to create the initial matrix with the variable element using a for loop, but I am having problems indexing the result matrix. I have tried several versions, but this is the latest. Any suggestions would be greatly appreciated. Thank you.
numbers <- c(4,5,length.out = 2)
A <- matrix(c(1,2,3,NA),nrow=2,ncol=2)
resul <- matrix(nrow=2,ncol=1)
for (i in 1:2) {
A[2,2]<- matrix(numbers[i])
N0 <- matrix(c(1,2),nrow=2,ncol=1)
resul[i,]<- A[i,i]%*%N0
}
Your code has two distinct problems. the first is that A[i,i] is a 1 x 1
matrix, so you're getting an error because your multiplying a 1 x 1 matrix
by a 2 x 1 matrix (N0).
you could either drop the subscript [i,i] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
# note the index is on the column b/c `A%*%N0` is a column matrix
result[,i]<- A%*%N0
}
or you could either drop the the second subscript [i,] and initialize the result to be
a two by two matrix like so:
result <- matrix(nrow=2,ncol=1)
for (i in 1:2){
A[2,2]<- matrix(numbers[i])
# a colunm vector
N0 <- matrix(c(1,2),
nrow=2,
ncol=1)
result[i,]<- A[i,]%*%N0
}
but it's not clear from you post which (if either) answer is the correct one. Indexing is tricky :)
Related
I want to replace values in a matrix based on matrix indexes stored in two vectors (one for x, another one for y). I did it some time ago but forgot the syntax for subsetting based on vectors.
Let's say i have this matrix and these 2 arrays:
m <- matrix(0,10,10)
x <- c(1,3,5)
y <- c(2,4,6)
And i need to replace m[1,2], m[3,4], m[5,6] with other value, what would be the syntax in this case? I tried m[x,y] but doesn't work.
Without sparse matrix support:
If we include z <- c(4.5,5.6,6.7) for the values then,
for(i in 1:length(z)) m[x[i],y[i]] <- z[i]
If you want to an apply solution, this is all I could think of,
apply(data.frame(x=x,y=y,z=z),1,function(row) .GlobalEnv$m[row[1],row[2]] <- row[3])
I remembered how it was, to subset a matrix from vectors the syntax is:
m[cbind(x,y)]
I have a large dataset, X with 58140 columns, filled with either 1 or 0
I would like to create a 58139 x 58139 matrix from the information of the 58139 columns in the dataset.
For each Aij in the matrix I would like to find the number of common rows which contain the value 1 for Column i+1 and Column J+1 from X.
I figured I can do this through sum(X[[2]]+X[[3]] == 2) for the A12 element of the matrix.
The only problem left is a way to code the matrix in.
You can use mapply. That returns a numeric vector. Then you can just wrap it in a call to matrix and ignore the first row and column.
# sample data
set.seed(123)
X <- data.frame(matrix(rbinom(200, 1, .5), nrow=10))
#
A <- matrix(mapply(function(i, j) sum(rowSums(X[, c(i,j)])==2),
i=rep(1:ncol(X), ncol(X)),
j=rep(1:ncol(X), each=ncol(X))),
ncol=ncol(X))[-1, -1]
A
I am trying to write a loop using "for" where my index,i, should have values from a set of values c(2,4,6,8,10,12) . I am further using i for subsetting values from another vector.
I defined a vector X , where X <- c(2,4,,6,8,10,12) ,
and then using for(i in X[1]:tail(X,n=1)).
This results in i taking all values from 2 to 12!
Whereas I want it to take the values mentioned in X only, i.e 2,4,6,8,10,12.
I hope someone can give me a hint how to do this
Thank you in advanced
You are looping through a sequence. If you want to loop only through the values of a vector, use this:
X <- c(2,4,6,8,10,12)
for(i in X) {
# Your code
}
So I know that if you have:
m = matrix(1:9, 3,3)
z = as.matrix(expand.grid(1:3, 1:3))
and you do
m[z]
# you get back 1 2 3 4 5 6 7 8 9
But if you do
m[] = m[z]
# You get back a matrix..
I'm a little confused as to what this [] operator does? why doesnt something like m[][z] or m[z][] return a matrix? and how would I get it to return a matrix without assigning it to a variable m[]
Thanks!
The key here is that when the argument to "[]" (which is really a function) is a two column matrix as you provided, the result will be a vector where the first column specifies the row and the second column specifies the column in operated-upon matrix. This is a "feature" ( and a very handy one I might add) of the language.
The arguments might or might not contain all of the possible combinations of row and column so the result would not predictably be something that would sensibly be a matrix of the same dimensions. The form: m[] <- m[ z[1:4, ] ] will produce a result but also a warning. You should look at the result and then make an effort to understand what is happening.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Randomly selecting values from an existing matrix after adding a vector (in R)
This is a follow up to my question from last week and can be found here. I wasn't sure if it was appropriate to post this question in the same place, or to post it as a new question.
Okay, last time I asked about randomly removing values from a matrix after binding a new vector to it. The answers were very useful, but I have found a bug when I am using a non square matrix. I have been running the code in a loop and taking the sum of the matrix each time to ensure that it is working properly, but I have found that the sum varies, which would imply that the code is sometimes selecting the wrong value in the matrix (I want it to only select and replace ones).
Here is the code:
mat1<-matrix(c(1,0,1,0, 0,1,1,1, 1,0,0,0, 1,0,0,1, 1,1,1,1, 0,0,0,1),byrow=F, nrow=4)
I.vec<-c(0,1,1,1,0,0)
foo <- function(mat, vec) {
nr <- nrow(mat)
nc <- ncol(mat)
cols <- which(vec == 1L)
rows <- sapply(seq_along(cols),
function(x, mat, cols) {
ones <- which(mat[,cols[x]] == 1L)
sample(ones, 1)
}, mat = mat, cols = cols)
ind <- (nr*(cols-1)) + rows
mat[ind] <- 0
mat <- rbind(mat, vec)
rownames(mat) <- NULL
mat
}
set.seed(2)
for (j in 1:1000){ #run this vector through the simulations
I.vec2=sample(I.vec,replace=FALSE) #randomize interactions
temp=foo(mat1,I.vec2) #run foo function
prop=sum(temp)
print.table(prop)
}
In this case, sometimes the sum of the matrix is 13 and sometimes it is 14, when it should always be = sum(mat1) = 13.
I've tried to pick apart the code, and I think everything is working correctly except for the rows function, which, admittedly, I do not fully understand.
The problem is a feature of sample(). I will update the original Q, but the problem is due to a single 1 being observed in a column in the candidate matrix. The code that generates rows is trying to sample from a set of 1. Unfortunately, I forgot that sample() has a feature that when the first argument is a vector of length 1, sample() treats it as if you wanted to sample from the set 1, ..., n where n was the value of the single element in the set youe really wanted to sample from.
A simple example illustrates the behaviour when the argument x to sample() is a length 1 vector:
> set.seed(1)
> replicate(10, sample(4, 1))
[1] 2 2 3 4 1 4 4 3 3 1
Instinctively, these should all be 4, but they aren't because of this documented and well known feature.