Skip to content
Prev 59464 / 63430 Next

surprised matrix (1:256, 8, 8) doesn't cause error/warning

FWIW, I paste below a possible change to the warnings generating part of the do_matrix function in R/src/main/array.c that adds the kind of warning that Abby is asking for, and that IMHO would more often help users find bugs in their code than interfere with intended behaviour.
[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
Warning message:
In matrix(1:12, nrow = 2, ncol = 3) :
 data length incompatible with size of matrix
Warning messages:
1: In matrix(1:7, nrow = 2, ncol = 3) :
 data length [7] is not a sub-multiple or multiple of the number of rows [2]
2: In matrix(1:7, nrow = 2, ncol = 3) :
 data length incompatible with size of matrix
Warning messages:
1: In matrix(1:8, nrow = 2, ncol = 3) :
 data length [8] is not a sub-multiple or multiple of the number of columns [3]
2: In matrix(1:8, nrow = 2, ncol = 3) :
 data length incompatible with size of matrix
<0 x 0 matrix>
[,1] [,2] [,3]
[1,]   NA   NA   NA
[2,]   NA   NA   NA
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    1    2    1    2    1    2

It would be nice to combine the new warning with that about ?...not a sub-multiple or multiple?? into a single warning, if appropriate (as in two of the examples above), but that would require bigger surgery way above my payscale.

Kind regards
	Wolfgang Huber


Index: array.c
===================================================================
--- array.c	(revision 79951)
+++ array.c	(working copy)
@@ -133,18 +133,19 @@
	    nc = (int) ceil((double) lendat / (double) nr);
    }

-    if(lendat > 0) {
+    if (lendat > 1) {
	R_xlen_t nrc = (R_xlen_t) nr * nc;
-	if (lendat > 1 && nrc % lendat != 0) {
+	if ((nrc % lendat) != 0) {
	    if (((lendat > nr) && (lendat / nr) * nr != lendat) ||
		((lendat < nr) && (nr / lendat) * lendat != nr))
		warning(_("data length [%d] is not a sub-multiple or multiple of the number of rows [%d]"), lendat, nr);
	    else if (((lendat > nc) && (lendat / nc) * nc != lendat) ||
		     ((lendat < nc) && (nc / lendat) * lendat != nc))
-		warning(_("data length [%d] is not a sub-multiple or multiple of the number of columns [%d]"), lendat, nc);
-	}
-	else if ((lendat > 1) && (nrc == 0)){
+		    warning(_("data length [%d] is not a sub-multiple or multiple of the number of columns [%d]"), lendat, nc);
+	if (nrc == 0)
	    warning(_("data length exceeds size of matrix"));
+        if (nrc != lendat)
+            warning(_("data length incompatible with size of matrix"));
	}
    }


------
// And here, for easy checking that part of the code in the new form:
 if (lendat > 1) {
	R_xlen_t nrc = (R_xlen_t) nr * nc;
	if ((nrc % lendat) != 0) {
	    if (((lendat > nr) && (lendat / nr) * nr != lendat) ||
		((lendat < nr) && (nr / lendat) * lendat != nr))
		warning(_("data length [%d] is not a sub-multiple or multiple of the number of rows [%d]"), lendat, nr);
	    else if (((lendat > nc) && (lendat / nc) * nc != lendat) ||
		     ((lendat < nc) && (nc / lendat) * lendat != nc))
		    warning(_("data length [%d] is not a sub-multiple or multiple of the number of columns [%d]"), lendat, nc);
	if (nrc == 0)
	    warning(_("data length exceeds size of matrix"));
       if (nrc != lendat)  
           warning(_("data length incompatible with size of matrix"));
	}
   }