This does appear to be a shortcoming in the '*' code. If I understand
Berwin's concerns correctly, here is a simpler example with matrix and
vector, which should generate a warning, but doesn't, and an example with
two vectors, which does generate a warning:
> matrix(1:6,2) * 1:4
[,1] [,2] [,3]
[1,] 1 9 5
[2,] 4 16 12
> 1:6 * 1:4
[1] 1 4 9 16 5 12
Warning message:
longer object length
is not a multiple of shorter object length in: 1:6 * 1:4
>
The operators "+", "-", "/", "%/%",
"^", "&", and "|" behave in a similar
manner (and switching the arguments does not change the behavior).
In S-plus 6.1, examples of this type stop with an error.
As far as I know, it is standard in the S language for "*" to treat
both
its arguments as vectors (dimension attributes are only used to construct
the dimension attributes of the returned value). So as Berwin notes, the
matrix * vector case should generate a warning when the lengths of the
arguments are not multiples.
The problem appears to be in the functions lbinary() in logic.c and
R_binary() in arithmetic.c -- length checking is not done at all if either
x or y is an array.
The fix in arithmetic.c is to move the block of code:> if (nx == ny || nx == 1 || ny == 1) mismatch = 0;
> else if (nx > 0 && ny > 0) {
> if (nx > ny) mismatch = nx % ny;
> else mismatch = ny % nx;
> }
from inside the else block of "if (xarray || yarray) {" to after the
end of
the else (so that it always gets executed) (also, as far as I can see the
first "if" that sets mismatch=0 is redundant and could be deleted).
The fix in logic.c is to move the block of code:> nx = length(x);
> ny = length(y);
> if(nx > 0 && ny > 0) {
> if(nx > ny) mismatch = nx % ny;
> else mismatch = ny % nx;
> }
from inside the else block of "if (xarray || yarray) {" to after the
end of
the else (so that it always gets executed).
With these changes (including the deletion of the redundant code) R 1.9.0
compiled and ran "make tests" with errors only in "running code
in
'reg-tests-3.R'" (which appeared due to not being able to find
packages
MASS and survival) and differences in the internet tests (as expected.)
-- Tony Plate
At Monday 09:57 PM 3/1/2004, berwin@maths.uwa.edu.au
wrote:>Dear all,
>
>While showing some commands of R to my students, I came across the
>following behaviour of * which surprised me.
>
> > set.seed(20) # to make it reproducible
> # create some objects
> > z <- matrix(rnorm(6), ncol=2) # 3x2 matrix
> > x1 <- rnorm(3) # vector of length 3
> > y1 <- rnorm(4) # vector of length 4
> > y2 <- matrix(y1, ncol=1) # 4x1 matrix
>
> > z*x1 # works fine, as expected
>
> > x1*y1 # warning message, as expected
>[1] 1.60535635 0.01749800 0.06943188 1.81510895
>Warning message:
>longer object length
> is not a multiple of shorter object length in: x1 * y1
>
> > z*y2 # also expected
>Error in z * y2 : non-conformable arrays
>
> > z*y1 # no warning, no error?
> [,1] [,2]
>[1,] -0.64591924 0.83703776
>[2,] 0.01179780 0.24808611
>[3,] -0.26850220 -0.01146923
>
> > x1*y2 # no warning, no error?
> [,1]
>[1,] 1.60535635
>[2,] 0.01749800
>[3,] 0.06943188
>[4,] 1.81510895
>
>I was expecting warning messages in the last examples.
>
>But after consulting the help page (?*) and the 'R Language
>definition', I am not sure what I should have expected. :)
>
>The help page says that "[t]hese binary operators perform arithmetic
>on vector objects" and "[o]bjects such as arrays [...] can be
operated
>on this way provided they are conformable". The R Language definition
>states "a vector is not the same as a one-dimensional array since the
>latter has a dim attribute of length one, whereas the former has no
>dim attribute".
>
>So technically, I guess, the last two examples are operations between
>a vector object and an array object. And the help page doesn't seem
>to say anything about this situation.
>
>I have a vague memory that there as been discussion on this subject in
>the (distant?) past, but unfortunately I don't remember what behaviour
>was deemed to be sensible. I also couldn't find any recent posts
>about this on the bug archives.
>
>Thus, after careful consideration I decided to fill out this bug
>report since I came to the conclusion that for these examples either
>a) both operands should have been treated as a vector objects and a
> warning message should have been issued; or
>b) the documentation should make it clear that the warning is not
> issued if one operates on a vector object and an array object.
>
>My apologies if this was already reported and I missed it in the bugs
>archives.
>
>Cheers,
>
> Berwin
>
>
>
>--please do not edit the information below--
>
>Version:
> platform = i686-pc-linux-gnu
> arch = i686
> os = linux-gnu
> system = i686, linux-gnu
> status > major = 1
> minor = 8.1
> year = 2003
> month = 11
> day = 21
> language = R
>
>Search Path:
> .GlobalEnv, package:methods, package:ctest, package:mva, package:modreg,
> package:nls, package:ts, Autoloads, package:base
>
>______________________________________________
>R-devel@stat.math.ethz.ch mailing list
>https://www.stat.math.ethz.ch/mailman/listinfo/r-devel