Convert a one column matrix to n x c matrix - r

I have a (nxc+n+c) by 1 matrix. And I want to deselect the last n+c rows and convert the rest into a nxc matrix. Below is what I've tried, but it returns a matrix with every element the same in one row. I'm not sure why is this. Could someone help me out please?
tmp=x[1:n*c,]
Membership <- matrix(tmp, nrow=n, ncol=c)

You have a vector x of length n*c + n + c, when you do the extract, you put a comma in your code.
You should do tmp=x[1:(n*c)].
Notice the importance of parenthesis, since if you do tmp=x[1:n*c], it will take the range from 1 to n, multiply it by c - giving a new range and then extract based on this new range.
For example, you want to avoid:
(1:100)[1:5*5]
[1] 5 10 15 20 25
You can also do without messing up your head with indexing:
matrix(head(x, n*c), ncol=c)

Related

nested loop matrix index in R

I am learning matrix multiplication in R and following is what I want to achieve. I am doing this purely to upscale my skills in R.
Following is the kind of matrix I am working with:
m <- matrix(1, 100, 10)
I have matrix with only element 1 with 100 rows and 10 columns. Now I want to replace for column 1 with 0 from row1 to row10. Then for the second column, I want to replace 1 with zeros from row 11 to row 20. Similarly for for the third column, I want to replace 1 with zeros from row 21 to row 30 and similarly for the rest up too column 10. Following my my example
m <- matrix(1, 100, 10)
for(j in 1:10){
for(i in (j-1)*10+1: j*10){
m[i,j] <-0
}
}
I was quite confident that my logic was correct but every time I run my code, I get following error message Subscripts out of bounds Call. I tried couple days now and I could not resolve this problem. I would highly appreciate for any hints or direct solutions to fix this. Many thanks in advance.
You could use just one variable, which I think would be easier. For each column, j, get the lower and upper range of row indices and assign as 0.
for(j in 1:10){
row_lower <- (j-1)*10+1
row_upper <- j*10
m[row_lower: row_upper, j] <- 0
}
Returns 0's in your specified range.

Is there a way to access an element in amultidimensional array using a variable to store the indexes

Let's say I have a matrix A with n rows and m columns. If I want to acess the element on the i'th row and j'th column I can access it as A[i,j].
I would like to know how I can save this i,j in a variable x so that I can get A[x] = A[i,j]. storing them in a vector won't help since A[i,j] != A[c(i,j)].
I would like to be able to do this for a higher dimensional array where I don't know the dimensions ahead of time because they depend on the data that is suploaded by the user.
thank you very much!
Edit
what I ended up doing:
If x is the vector representing the Indices I needed, the solution is A[matrix(x,nrow=1))
You can use cbind or calculate the position.
A <- matrix(1:12, 3)
A[2,3]
#8
A[3,1]
#3
i <- c(2,3)
j <- c(3,1)
x <- cbind(i,j)
A[x]
#[1] 8 3
x <- i + (j-1)*dim(A)[1]
A[x]
#[1] 8 3

Muliplying Elements of a Vector one more each time

I am trying to create a vector from another vector where I multiply the numbers in the vector one more each time.
For example if I had (1,2,3) the new vector would be (1, 1 x 2, 1 x 2 x 3)=(1,2,6)
I tried to create a loop for this as seen below. It seems to work for whole numbers but not decimals. I am not sure why.
x <- c(0.99,0.98,0.97,0.96,0.95)
for(i in 1:5){x[i]=prod(x[1:i])}
The result given is 0.9900000 0.9702000 0.9316831 0.8590845 0.7303385
which is incorrect as prod(x) = 0.8582777. Which is not the same as the last element of the vector.
Does anyone know why this is the case? Or have a suggestion for improvement in my code to get the correct answer.
test<-c(1,2,3)
cumprod(test)
[1] 1 2 6
As #akrun suggests, one can achieve the same with:
Reduce("*", test, accumulate = TRUE)

How to add a constant in a for loop by keeping the original matrix in each iteration?

For example,
x<-matrix(c(1,2,3,4),2,2)
1 2
3 4
I want to add the constant "c" to each element of the matrix separately like this.
Iteration 1
1+c 2
3 4
Iteration 2
1 2+c
3 4
Iteration 3
1 2
3+c 4
Iteration 4
1 2
3 4+c
I have tried the following R code, but it retains the updated value while performing second iteration.
x= matrix of order nxm
for(i in 1:r)
{
for(j in 1:c)
{
x[i,j]=x[i,j]+c
print(x)
}
}
In this code the values getting updated and printing the updated value for each iteration.
Please help me... Thanks in Advance.
R prefers array operations.
Any matrix x is just an array of its entries, laid out column by column. You may successively add the constant c to the first, second, third, ... entry to copies of x, so that the original x remains unchanged. Do this by constructing arrays of the same length as x with all zero entries except for c in the desired location. The code shown at the end of this post does this by concatenating a bunch of zeros, c, and more zeros so that c appears in position i:
c(rep(0,i-1), cnst, rep(0,n-i)
If you loop with i=1, 2, 3, etc, the results will work down through each column of x, moving left to right. To do the operations in the order presented in the question, which works through each row, moving top to bottom, simply apply the procedure to the transpose of x and transpose the outputs.
Even for large matrices, this approach of adding an entire array is at least twice as fast on my system as adding c just to the i position of a copy of x.
Here is R code for the general procedure. It works on any non-empty matrix x. Beware: the output consists of length(x) copies of x and therefore can be quite large. In this example--which takes about a second to run on my system--x has 10,000 entries and therefore the output has 100,000,000 entries. You might want to test it on smaller matrices first!
x <- matrix(1:(100^2), 100) # Any nonempty matrix
cnst <- 1 # Value to add successively to each term in `x`
#
# The algorithm begins here.
#
n <- length(x)
lapply(1:n, function(i) matrix(as.vector(x)+c(rep(0,i-1),cnst,rep(0,n-i)), nrow(x)))
You just need to make a copy of the matrix:
x_safely_stored <- matrix of order nxm
for(i in 1:r) {
for(j in 1:c) {
x <- x_safely_stored
x[i,j]=x[i,j]+c
print(x)
}
}

Convert vector into a triangular matrix

I have a vector of 874! elements, which I want to turn into a triangular matrix (i.e. the top right hand corner of a square matrix).
Example Input:
1
2
3
4
5
6
7
8
9
10
Example Output:
1 2 4 7
3 5 8
6 9
10
Blanks could be filled with NAs. I'd prefer if the matrix were this way around.
I don't know which programming language do you want to use neither do I understand which order do you want your numbers to be stored in.
You should consider that having N elements, if you want to generate an square matrix its dimensions (n rows and columns) are given by:
N = (n*(n+1))/2
So a first approach (you should consider if your input vector has x^2/2 elements) in Python could be:
from math import sqrt
x = range(1,25+1) # This is your input vector
N = len(x)
#N = (n*(n+1))/2 # Number of elements being stored in a triangular matrix.
n = (-1.0+sqrt(1.0+8.0*N))/2.0 # Solve the equation given by the previous relation.
n = int(round(n)) # Making it integer...
while (n*(n+1))/2 < N: # ... losing precission so we should use the first n being able ...
if (n*(n+1))/2 < N: # ... to store your vector is used.
n += 1
res = [[0]*n for i in xrange(n)] # Here, we create a n*n matrix filled with zeros.
x = x[::-1] #Reverse the input so it can be consumed using pop (O(1) each extraction)
for j in xrange(n): # Fill the empty matrix following the triangular pattern and using...
if not x:
break
for i in xrange(j+1):
if not x:
break
res[i][j] = x.pop() # The elements from your input vector.
for row in res: # Let's print the result!
print(row)
The idea is to consume x filling the square matrix (res) with is values in the right order. This can easily done once you now your target matrix dimesions.

Resources