> On Jul 13, 2017, at 5:07 PM, Marc Schwartz <marc_schwa...@me.com> wrote: > > >> On Jul 13, 2017, at 3:37 PM, Marc Schwartz <marc_schwa...@me.com> wrote: >> >> >>> On Jul 13, 2017, at 3:22 PM, Duncan Murdoch <murdoch.dun...@gmail.com> >>> wrote: >>> >>> On 13/07/2017 4:08 PM, Marc Schwartz wrote: >>>> Hi All, >>>> >>>> As per the discussion today on R-Help: >>>> >>>> https://stat.ethz.ch/pipermail/r-help/2017-July/448132.html >>>> >>>> I am attaching a proposed patch for poly.Rd to provide clarifying wording >>>> relative to naming the 'degree' argument explicitly, in the case where the >>>> 'x' argument is a matrix, rather than a vector. >>>> >>>> This is based upon the svn trunk version of poly.Rd. >>> >>> I don't think this is the right fix. The use of the unnamed 2nd arg as >>> degree happens whether the first arg is a matrix or not. >>> >>> I didn't read the whole thread in detail, but it appears there's a bug >>> somewhere, in the report or in the poly() code or in the plsr() code. That >>> bug should be reported on the bug list if it turns out to be in base R, and >>> to the package maintainer if it is in plsr(). >>> >>> Duncan Murdoch >> >> >> Duncan, >> >> Thanks for your reply. You only really need to read that last post in the >> thread linked to above. >> >> I won't deny the possibility of a bug in poly(), relative to the handling of >> 'x' as a matrix. The behavior occurs in the poly() function in a pure stand >> alone fashion, without the need for plsr(): >> >> x1 <- runif(20) >> x2 <- runif(20) >> mx <- cbind(x1, x2) >> > > <snip> > > Duncan, > > Tracing through the code for poly() using debug once with: > > poly(mx, 2) > > and then with: > > poly(mx, degree = 2) > > there is a difference in the transformation of 'mx' internally by the use of: > > if (is.matrix(x)) { > m <- unclass(as.data.frame(cbind(x, ...))) > return(do.call(polym, c(m, degree = degree, raw = raw, list(coefs = > coefs)))) > } > > > In the first case, 'mx' ends up being transformed to: > > Browse[2]> m > $x1 > [1] 0.99056941 0.13953093 0.38965567 0.35353514 0.90838486 0.97552474 > [7] 0.01135743 0.06537047 0.56207834 0.50554056 0.96653391 0.69533973 > [13] 0.31333549 0.97488211 0.54952630 0.71747157 0.31164777 0.81694822 > [19] 0.58641410 0.08858699 > > $x2 > [1] 0.6628658 0.9221436 0.3162418 0.8494452 0.4665010 0.3403719 > [7] 0.4040692 0.4916650 0.9091161 0.2956006 0.3454689 0.3331070 > [13] 0.8788974 0.5614636 0.7794396 0.2304009 0.6566537 0.6875646 > [19] 0.5110733 0.4122336 > > $V3 > [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 > > attr(,"row.names") > [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 > > Thus, when do.call() is used, m$V3 is passed as the 'x' argument on the third > iteration, essentially resulting in: > >> polym(rep(2, 20), degree = 2) > Error in poly(dots[[1L]], degree, raw = raw, simple = raw && nd > 1) : > 'degree' must be less than number of unique points > > > Note also that in this case, 'dots', which is the result of using list(...) > on the initial call, is: > > Browse[2]> dots > [[1]] > [1] 2 > > > In the second case: > > Browse[2]> m > $x1 > [1] 0.99056941 0.13953093 0.38965567 0.35353514 0.90838486 0.97552474 > [7] 0.01135743 0.06537047 0.56207834 0.50554056 0.96653391 0.69533973 > [13] 0.31333549 0.97488211 0.54952630 0.71747157 0.31164777 0.81694822 > [19] 0.58641410 0.08858699 > > $x2 > [1] 0.6628658 0.9221436 0.3162418 0.8494452 0.4665010 0.3403719 > [7] 0.4040692 0.4916650 0.9091161 0.2956006 0.3454689 0.3331070 > [13] 0.8788974 0.5614636 0.7794396 0.2304009 0.6566537 0.6875646 > [19] 0.5110733 0.4122336 > > attr(,"row.names") > [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 > > > So, there is no m$V3. > > Note also that 'dots' ends up being: > > Browse[2]> dots > list() > > > In both cases, 'degree' is indeed 2, but the result of 'list(...)' on the > initial function call is quite different. > > So, I may be hypo-caffeinated, but if there is a bug here, it may be due to > the way in which cbind() is being called in the code above, where the three > dots are being used? > > I can replicate the presumably correct behavior by using: > > m <- unclass(as.data.frame(cbind(x))) > > instead of: > > m <- unclass(as.data.frame(cbind(x, ...))) > > But I am not sure if removing the three dots in the cbind() call may have > other unintended consequences. > > Regards, > > Marc
Duncan, Some additional information here. Reviewing the source code for the function in SVN: https://svn.r-project.org/R/trunk/src/library/stats/R/contr.poly.R there is a relevant comment in the code: if(is.matrix(x)) { ## FIXME: fails when combined with 'unnamed degree' above m <- unclass(as.data.frame(cbind(x, ...))) return(do.call(polym, c(m, degree = degree, raw = raw, list(coefs=coefs)))) } A version review would suggest that the above comment was added to the code back in 2015. So it would appear that the behavior being discussed here is known. I am still confused by the need for the '...' in the call to cbind(), which as far as I can tell, has been in the code at least back to 2003, when the poly() code was split from base. I am not sure why one would want to pass on other '...' arguments to cbind(), but I am presumably missing something here. Regards, Marc ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel