# Re: [R] diag() problem

From: Duncan Murdoch <murdoch_at_stats.uwo.ca>
Date: Thu 20 Oct 2005 - 02:20:47 EST

On 10/19/2005 11:37 AM, Prof Brian Ripley wrote:

```> 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)) ...
>

```

I agree with your objection; I realized the same thing just after I posted my original. The solution I came up with was putting the all() in isTRUE(). I think that achieves an identical result to your solution.

Can you see any reason to prefer one over the other?

Duncan Murdoch

R-help@stat.math.ethz.ch mailing list