Re: [R] diag() problem

From: Prof Brian Ripley <ripley_at_stats.ox.ac.uk>
Date: Thu 20 Oct 2005 - 01:37:57 EST

On Wed, 19 Oct 2005, Duncan Murdoch wrote:

> On 10/19/2005 10:55 AM, Robin Hankin wrote:

>> Hi
>>
>> I have a matrix "u", for which diag() gives an error:
>>
>> u <- structure(c(5.42334674128216, -2.31319389204264, -5.83059042218476,
>>   -1.64112369640695, -2.31319389212801, 3.22737617646609,
>> 1.85200668021569,
>>   -0.57102273078531, -5.83059042231881, 1.85200668008156,
>> 11.9488923894962,
>>   -3.5525537165941, -1.64112369587405, -0.571022730886046,
>> -3.55255371755604,
>>   10.0989829379577), .Dim = c(4, 4), .Dimnames = list(c("constant",
>>   NA, NA, NA), c("constant", NA, NA, NA)))
>>
>> > u
>>            constant       <NA>      <NA>       <NA>
>> constant  5.423347 -2.3131939 -5.830590 -1.6411237
>> <NA>     -2.313194  3.2273762  1.852007 -0.5710227
>> <NA>     -5.830590  1.8520067 11.948892 -3.5525537
>> <NA>     -1.641124 -0.5710227 -3.552554 10.0989829
>> > is.matrix(u)
>> [1] TRUE
>> > diag(u)
>> Error in if (is.list(nms) && !any(sapply(nms, is.null)) && all((nm <-
>> nms[[1]][1:m]) ==  :
>>      missing value where TRUE/FALSE needed
>>
>> >
>>
>>
>> What's going on here?
>

> It's trying to check whether the row names match the column names, in
> which case it will assign those names to the diagonal elements. But the
> writer didn't figure someone would have NA names, so the test
>

> all((nm <- nms[[1]][1:m]) == nms[[2]][1:m])
>

> fails.
>

> It could be "fixed" by putting "na.rm=TRUE" into the all(), but that's
> probably not right:
>

> > all(c(1, NA) == c(1, 2), na.rm = TRUE)
> [1] TRUE
>

> I think we want to wrap the values in "paste", to convert to non-missing
> characters. That would be
>

> all(paste((nm <- nms[[1]][1:m])) == paste(nms[[2]][1:m]))
>

> and would give
>

> > diag(u)
> constant <NA> <NA> <NA>
> 5.423347 3.227376 11.948892 10.098983
>
> Any objections to me committing this change?

Yes, you don't want <NA> to match "NA".

If you think NA names should match, use identical. Otherwise (and I think this would be more consistent with other parts of R), do something like

eq <- (nm <- nms[[1]][1:m]) == nms[[2]][1:m] if(all(!is.na(eq) && eq)) ...

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Thu Oct 20 01:47:04 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:40:46 EST