##### vector/matrix annoyances # For illustration, we use vectors v1_4 and v2_4, and the matrix m1_24. v1_4 <- c(1,3,5,7) v2_4 <- c(2,4,6,8) m1_24 <- matrix(c(1,3,5,7, 2,4,6,8),nrow=2,byrow=TRUE) # In many cases, R treats vectors and matrices in similar, logical ways. # Vectors are generally treated as column vectors. # Note, however: v1_4 %*% v2_4 # = 100 # and t(v1_4) %*% v2_4 # Same # For the outer product, we must use, as expected v1_4 %*% t(v2_4) # In some operations, such as t(), cbind(), and rbind(), a vector is promoted to a matrix: is.matrix(v1_4) # FALSE is.matrix(t(v1_4)) # TRUE is.matrix(cbind(v1_4)) # TRUE is.matrix(rbind(v1_4)) # TRUE # Many R functions that operate on matrices, the dim attribute is used. # The dim() function requires that the argument be a matrix (or array or data frame) dim(v1_4) # NULL dim(t(v1_4)) # 1 4 dim(t(t(v1_4))) # 4 1 dim(m1_24) # 2 4 # The fact that dim(v1_4) is NULL can interfer with many natural operations. # apply(), for example, requires a non-NULL value of dim(). apply(v1_4,1,var) # yields error apply(t(v1_4),1,var) # yields 6.666667 apply(m1_24,1,var) # yields 6.666667 6.666667 # If the expression apply(x,1,var) is in a general script with x input # and x may be a vector (one variable) or a matrix (several variables) # we must form xx<-as.matrix(x) x<-v1_4 # One way to do this in the general script is: if (is.matrix(x)) xx<-x else xx<-as.matrix(x) apply(xx,2,var) # Another problem is what happens when the subarray constructor is used. # If the result has only one row or column, the result is demoted to a vector is.matrix(m1_24[1:2,]) # TRUE is.matrix(m1_24[1:2,1:2]) # TRUE is.matrix(m1_24[1:2,1]) # FALSE is.matrix(m1_24[1:2,1:1]) # FALSE is.matrix(m1_24[1,1:2]) # FALSE # Hence, dim(m1_24[1:2,1:1]) is null # This can cause problems in general R scripts when the limits on the # column or row indexes are variables.