Select a column of matrix in r by looping - r

I have a matrix:
mvn.var=matrix(c(3,1,1,4,6,7,8,9),4,2,byrow=T)
And I try
for (i in 1:dim(mvn.var)[2]) {
y[i]=mvn.var[,i]
}
Because I want to have vectors y[i] where y[i] is a vector that consists of the elements of the i-th column of the previous mvn.var matrix.
I get:
Warning messages:
1: In y[i] = mvn.var[, i] :
number of items to replace is not a multiple of replacement length
2: In y[i] = mvn.var[, i] :
number of items to replace is not a multiple of replacement length

You are trying to assign to an element of the vector. Try this instead,
mvn.var=matrix(c(3,1,1,4,6,7,8,9),4,2,byrow=T)
y = matrix(data=NA,2,4,byrow=T)
for (i in 1:dim(mvn.var)[2]) {
y[i,]=mvn.var[,i]
}
However you can achieve the same result by merely transposing your matrix, e.g., t(mvn.var).

You try to put a vector of length 4 into something of length 1 (=i'th element of y). The message warns you, because y[i] will only contain the first element of the column.
Try making y a list:
mvn.var=matrix(c(3,1,1,4,6,7,8,9),4,2,byrow=T)
y <- list()
for (i in 1:dim(mvn.var)[2])
y[[i]]=mvn.var[,i]
y
# [[1]]
# [1] 3 1 6 8
#
# [[2]]
# [1] 1 4 7 9

Related

Putting generated data in a matrix format

I have one question about putting a simulated data in a matrix format, but I cannot suitably write its program in R, and constantly receive an error, I guess my "rep" definition and final "Matrix" expression are somehow wrong, but I do not know how to fix them. Here my specific question is:
I would like to produce a matrix contains generated values. I have 20000 generated values for x and y. As the output, I like to have a (2000 by 10) matrix that each column of the matrix contains the output of following for loop.
My R.code:
x=rnorm(2e4,5,6)
vofdiv=quantile(x,probs=seq(0,1,0.1))
y=rnorm(2e4,4,6)
Matrix=rep(NULL,2000)
for(i in 1:10)
{
Matrix[i]=y[(x>=vofdiv[i] & x<vofdiv[i+1])] #The i(th) col of matrix
}
Matrix # A 2000*10 Matrix, as the final output
I highly appreciate that someone helps me!
You have several problems here.
First of all, the correct way to define an empty matrix of size 2e4*10, would be
Matrix <- matrix(NA, 2e4, 10)
Although you could potentially create a matrix using your way(rep) and then use dim, something like
Matrix <- rep(NA, 2e5)
dim(Matrix) <- c(2e4, 10)
Second problem is, when trying to insert into a column in a matrix, you need to index it correctly, i.e.,
Matrix[, i] <-
instead of
Matrix[i] <-
The latter will index Matrix as if it was a vector (which is it basically is). In other words, it will convert a 2000*10 matrix to a 20000 length single vector and index it.
The third problem is, that when your loop reaches i = 11 and you are running x<vofdiv[i+1] you are always excluding the last values which are x == vofdiv[11], thus you are always getting less than 2000 values:
for(i in 1:10)
{
print(length(y[ (x >= vofdiv[i] & x < vofdiv[i+1])]))
}
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 2000
# [1] 1999 <----
Thus, it will give you an error if you will try to replace 2000 length vector with 1999 length one, because a matrix in R can't contain different dimensions for each column.
The workaround would be to add = to your last statement, such as
Matrix <- matrix(NA, 2e4, 10)
for(i in 1:10)
{
Matrix[, i] <- y[x >= vofdiv[i] & x <= vofdiv[i + 1]]
}

FOR loop in R; not getting what I want

Just a general question:
When I run:
ok<-NULL
for (i in 1:3) {
ok[i]=i^2
i=i+1
}
The loop works (as expected).
> ok
[1] 1 4 9
Now when I try to do something like:
ok<-NULL
for (i in 1:3) {
ok[i]=i^2
x[i]<-ok[i]+1
y[i]<-cbind(ok[i],x)
i=i+1
}
And I want:
y = 1
2
4
5
9
10
Instead I get:
Warning messages:
1: In y[i] <- rbind(ok[i], x) :
number of items to replace is not a multiple of replacement length
2: In y[i] <- rbind(ok[i], x) :
number of items to replace is not a multiple of replacement length
3: In y[i] <- rbind(ok[i], x) :
number of items to replace is not a multiple of replacement length
4: In y[i] <- rbind(ok[i], x) :
number of items to replace is not a multiple of replacement length
5: In y[i] <- rbind(ok[i], x) :
number of items to replace is not a multiple of replacement length
Thanks in advance.
You should read up on R basics before starting to program.
You don't have to increment i in the loop (actually its quite confusing).
You don't cbind or rbind vectors this is for data.frame columns and rows.
y <- NULL
for(i in 1:3){ ok <- i^2; x <- ok + 1; y <- c(y, ok, x) }
or:
as.vector(sapply(1:3, function(i){ ok <- i^2; x <- ok + 1; c(ok, x) }))
With this command y[i]<-cbind(ok[i],x) you attempt to replace one element in the vector with several. This causes an error.
If you want to to get 1:3 squared, you would use:
ok <- (1:3)^2
ok
# [1] 1 4 9
If you want to get 1:3 squared, along with the numbers right after them, you might try:
as.vector(rbind(ok, ok+1))
[1] 1 2 4 5 9 10
for loops in R are often the wrong solution to your problem.

How do I print values in a list that are greater than a certain number along with the row name in R?

I am painfully new to R. I have a list of data, and I wrote a loop to find which values are greater than a certain number:
for (i in listname){
if(i > x)
print(i)
}
I would like for the printed values to also include the row name... how would I go about doing that?
Thanks for your patience.
Strangely, when the item itself is the iterator, the name is lost. If you instead iterate over the number of the item, print works as expected:
for (i in 1:length(listname)){
if (listname[i] > x){
print(listname[i]) # value with name
}
}
Once you've learned more about R, you will probably want to do this in a "vectorized" way, instead of using a loop:
idx <- which(listname > x) # row numbers
listname[idx] # values with names
or with logical subsetting
gt_x<- listname > x # TRUE or FALSE
listname[gt_x] # values with names
Example: Try this with
listname <- 1:10
names(listname) <- letters[1:10]
x <- 4
idx <- which(listname > x) # row numbers
listname[idx] # values with names
# e f g h i j
# 5 6 7 8 9 10

R: If the last column element in the previous row is NA, make current row NA

I am writing a function that will take the largest elements in a vector V.Size and output into a matrix N by N+1. My problem is when V.Size is smaller than N*(N+1). When this happens, the matrix starts by going to the top of the vector while I want it to output NAs.
For example:
# vector V.size is
V.size <- c(1,2,3,4,5,6)
# and N is
N <- 2
# then, the output matrix should be
c1 c2 c3
r1 6 5 4
r2 3 2 1
And when N*(N+1) > V.Size, I want V.Size to fill it until V.Size runs out then return NAs instead of starting over.
My attempt to solve this problem is by by searching for when an element is larger than the previous and replacing it with an NA. My attempted solution returns the error:
Error in if (is.na(m)[(i - 1), (y + 1)]) { : argument is of length zero
Here's my code:
# Function Name: one
# Input: V.Size (a vector) and N
# Output: Matrix size N by N+1
# Code:
one <- function(x,y) {
# sort the data, largest to smallest with N.A. last
temp <- sort(x, decreasing = TRUE, na.last = TRUE)
#creating the matrix
m <- matrix(head(temp, (y*(y+1))), # only takes elements that fit in the matrix
nrow = y, # number of rows = N
ncol = (y+1), # number of columns = N+1
byrow = TRUE) # filling it by row as instructed
if (length(x) < (y*(y+1))) { # if V.Size is smaller than the outputted matrix
for (i in seq_len(y)) { # for loop for columns
for (j in seq_len(y+1)) { # for loop for rows
if (m[i, j] > m[i,1]) { # if the element is larger than the first in the row
m[i, j] = NA # return NA
}
# HERE IS WHERE THINGS FAIL:
if (is.na(m)[(i-1), (y+1)]) { # if the last element in the previous row is NA
m[i, ] = NA # make current row NA
}
}
}
}
# print the output
m
}
# creating dummy data
V.Size <- c(1:10)
# choosing a dummy N
N = 5
one(V.Size, N)
I get the error: Error in if (is.na(m)[(i - 1), (y + 1)]) { : argument is of length zero
How about this?
V.size <- 1:6
N <- 3
matrix(sort(V.size, decreasing=TRUE)[1:(N*(N+1))], nrow=N, byrow=TRUE)
[,1] [,2] [,3] [,4]
[1,] 6 5 4 3
[2,] 2 1 NA NA
[3,] NA NA NA NA
I think the problem is in first time run of the loop. You shouldn't check for the condition when loop runs for first time. i.e. when i-1 = -1 or i=1 then no check. There whould no previous member for the first time run!!!

Sum each element of a vector with each element of a second vector

I have two vectors and I want a matrix which elements are the sum of each element of vector 1 and each element of vector 2.
For example, the first element in the first row of this matrix is the sum of the first element of vector 1 and the first element of vector 2; the second element of the first row is the sum of the first element of vector 1 and the second element of vector 2 and so on.
For example, with these two vectors
u <- c(1,2,3)
v <- c(4,5,6)
The desired result would be:
# [,1] [,2] [,3]
# [1,] 5 6 7
# [2,] 6 7 8
# [3,] 7 8 9
What I have tried:
A <- matrix( c(1:6), 3, 3 )
for(i in 1:3)
{
for(j in 1:3)
{
A[j][i] <- u[i]+v[j]
}
}
But I get some warnings:
Warning messages:
1: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
2: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
3: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
4: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
5: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
6: In A[j][i] <- u[i] + v[j] :
number of items to replace is not a multiple of replacement length
Can anybody help me?
This is how you would do it (note the matrix subset is not two brackets, but comma separated):
u <- c(1,2,3)
v <- c(4,5,6)
A <- matrix( c(1:6), 3, 3 )
for(i in 1:3)
{
for(j in 1:3)
{
A[i,j] <- u[i]+v[j]
}
}
But this is not the way someone who knows R would approach it. In general there are better ways to do things in R than nested for-loops. Another way is:
A <- outer(u,v,`+`)
We can also use sapply
sapply(u, `+`, v)

Resources