76

I am new to R. I want to fill in an empty matrix with the results of my for loop using cbind. My question is, how can I eliminate the NAs in the first column of my matrix. I include my code below:

output<-matrix(,15,) ##generate an empty matrix with 15 rows, the first column already filled with NAs, is there any way to leave the first column empty?

for(`enter code here`){
  normF<-`enter code here`
  output<-cbind(output,normF)
}

The output is the matrix I expected. The only issue is that its first column is filled with NAs. How can I delete those NAs?

micstr
  • 5,080
  • 8
  • 48
  • 76
user3276582
  • 761
  • 1
  • 5
  • 3

4 Answers4

107

The default for matrix is to have 1 column. To explicitly have 0 columns, you need to write

matrix(, nrow = 15, ncol = 0)

A better way would be to preallocate the entire matrix and then fill it in

mat <- matrix(, nrow = 15, ncol = n.columns)
for(column in 1:n.columns){
  mat[, column] <- vector
}
Christopher Louden
  • 7,540
  • 2
  • 26
  • 29
  • I found that in the second method, if the vector size was unknown, the third line would be `mat[1:length(vector), column] <- vector` to allow NA padding for the matrix. – BLiu1 Jan 18 '20 at 11:25
  • 1
    It worked great! If you are neurotic like me and want to avoid the exclamation mark pinpointing a "missing argument to function", then you can just use matrix(NA, nrow = 15, ncol = 0) instead of matrix(, nrow = 15, ncol = 0) – Rolando Gonzales Aug 28 '21 at 12:38
19

If you don't know the number of columns ahead of time, add each column to a list and cbind at the end.

List <- list()
for(i in 1:n)
{
    normF <- #something
    List[[i]] <- normF
}
Matrix = do.call(cbind, List)
Señor O
  • 17,049
  • 2
  • 45
  • 47
7

I'd be cautious as dismissing something as a bad idea because it is slow. If it is a part of the code that does not take much time to execute then the slowness is irrelevant. I just used the following code:

for (ic in 1:(dim(centroid)[2]))
{
cluster[[ic]]=matrix(,nrow=2,ncol=0)
}
# code to identify cluster=pindex[ip] to which to add the point
if(pdist[ip]>-1)
{
cluster[[pindex[ip]]]=cbind(cluster[[pindex[ip]]],points[,ip])
}

for a problem that ran in less than 1 second.

1

To get rid of the first column of NAs, you can do it with negative indexing (which removes indices from the R data set). For example:

output = matrix(1:6, 2, 3) # gives you a 2 x 3 matrix filled with the numbers 1 to 6

# output = 
#           [,1] [,2] [,3]
#     [1,]    1    3    5
#     [2,]    2    4    6

output = output[,-1] # this removes column 1 for all rows

# output = 
#           [,1] [,2]
#     [1,]    3    5
#     [2,]    4    6

So you can just add output = output[,-1]after the for loop in your original code.

Sheldon
  • 1,215
  • 1
  • 15
  • 29
  • Or as in Christopher's answer, you can start with a matrix that has no columns as ```output = matrix(,15,0)``` – Sheldon Sep 21 '18 at 17:17