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 https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html