ripley@stats.ox.ac.uk
1999-Aug-05 11:28 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
(1) ?cbind claims The generic functions `cbind' and `rbind' take a sequence of vector and/or matrix arguments and combine them as the columns or rows, respectively, of a matrix. Note: The method dispatching is not done via `UseMethod(..)', but by C-internal dispatching. Therefore, there's no need for, e.g., `rbind.default'. but my cbind.ts does not get called, and try the following: cbind.my <- function(...) { stop("used cbind.my") } a <- b <- 1:3 cbind(a, b) class(a) <- "my" cbind(a, b) [,1] [,2] [1,] 1 1 [2,] 2 2 [3,] 3 3 This is incorrect. (2) S would give a b [1,] 1 1 [2,] 2 2 [3,] 3 3 (and stop on the second cbind call). and this discrepancy is hardly an improvement! Could someone who can understands the c/rbind code please sort this out. (It looks pretty arcane to me, and surely should not be special-casing data frames.) I used both of> R.version_ platform sparc-sun-solaris2.6 arch sparc os solaris2.6 system sparc, solaris2.6 status status.rev 0 major 0 minor 64.2 year 1999 month July day 3 language R> R.version_ platform sparc-sun-solaris2.6 arch sparc os solaris2.6 system sparc, solaris2.6 status Under development (unstable) status.rev 0 major 0 minor 65.0 year 1999 month August day 05 language R -- 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 272860 (secr) Oxford OX1 3TG, UK Fax: +44 1865 272595 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Peter Dalgaard BSA
1999-Aug-05 13:57 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
ripley@stats.ox.ac.uk writes:> (1) ?cbind claims > > The generic functions `cbind' and `rbind' take a > sequence of vector and/or matrix arguments and combine > them as the columns or rows, respectively, of a matrix. > > Note: > > The method dispatching is not done via `UseMethod(..)', > but by C-internal dispatching. Therefore, there's no > need for, e.g., `rbind.default'. > > but my cbind.ts does not get called, and try the following: > > cbind.my <- function(...) > { > stop("used cbind.my") > } > a <- b <- 1:3 > cbind(a, b) > class(a) <- "my" > cbind(a, b) > [,1] [,2] > [1,] 1 1 > [2,] 2 2 > [3,] 3 3 > > This is incorrect. > > (2) S would give > a b > [1,] 1 1 > [2,] 2 2 > [3,] 3 3 > (and stop on the second cbind call). > > and this discrepancy is hardly an improvement! > > Could someone who can understands the c/rbind code please sort this out. > (It looks pretty arcane to me, and surely should not be special-casing data > frames.)Hmm. (1) The docs are clearly wrong (or perhaps rather, wishful thinking) (2) Cbind should be generic as in Splus (3) For the labels, one needs essentially to implement deparse.level or face the horrors of eval(substitute(cbind(a,b,deparse.level=2),list(a=rnorm(10),b=rnorm(10)))) (4) The dataframe special casing seems to be an evasion. The sticky bit is that one needs to dispatch on *any* argument. For Splus (3.4) compatibility, one has to check each argument for its class method, and if all arguments agree - in the sense that all the arguments that have class methods must have the same one, dispatch to that method. If they disagree, print error message and try default method. Whoever wrote the code seems to have decided that things would be easier if one assumed that the only method for cbind was cbind.data.frame... Note that by the above logic, if you make a cbind.ts, you can't cbind a time series to a data frame! -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Ross Ihaka
1999-Aug-05 21:53 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
On Thu, Aug 05, 1999 at 01:28:05PM +0200, ripley@stats.ox.ac.uk wrote:> Could someone who can understands the c/rbind code please sort this out. > (It looks pretty arcane to me, and surely should not be special-casing data > frames.)[ That would be a member of an empty subset of the developers. :-) ] I can see what the problem is - we don't have the generic dispatch mechanism in place. I will add it. I think that the special casing of data frames is needed because this appears to be the (undocumented) S behaviour. A data frame anywhere in the argument list causes the result to be a data frame. Ross -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
ihaka@stat.auckland.ac.nz
1999-Aug-05 22:29 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
On Fri, Aug 06, 1999 at 12:08:05AM +0200, Peter Dalgaard BSA wrote:> Ross Ihaka <ihaka@stat.auckland.ac.nz> writes: > > > I can see what the problem is - we don't have the generic dispatch > > mechanism in place. I will add it. > > > > I think that the special casing of data frames is needed because this > > appears to be the (undocumented) S behaviour. A data frame anywhere in > > the argument list causes the result to be a data frame. > > I played around with this earlier today. There's nothing special about > dataframes, S does the same with any classed object. I.e. > > class(b)<-"my" > cbind.my<-function(...)match.call() > > cbind(a,b) > > will dispatch cbind.myYetch! What happens when there are conflicting classes I wonder. [ Rhetorical question. ] It sounds like this might make things easier. Ross -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
ihaka@stat.auckland.ac.nz
1999-Aug-06 02:54 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
On Fri, Aug 06, 1999 at 12:08:05AM +0200, Peter Dalgaard BSA wrote:> Ross Ihaka <ihaka@stat.auckland.ac.nz> writes: > > I played around with this earlier today. There's nothing special about > dataframes, S does the same with any classed object. I.e. > > class(b)<-"my" > cbind.my<-function(...)match.call() > > cbind(a,b) > > will dispatch cbind.myI played some more. I think data frames are special somehow. S> x <- factor(1:10) S> y <- data.frame(1:10) > class(x) [1] "factor" S> class(y) [1] "data.frame" S> class(cbind(x,y)) [1] "data.frame" S> class(cbind(y,x)) [1] "data.frame" They seem to overpower other class arguments too. Ross -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
p.dalgaard@biostat.ku.dk
1999-Aug-06 07:34 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
Ross Ihaka <ihaka@stat.auckland.ac.nz> writes:> On Fri, Aug 06, 1999 at 12:08:05AM +0200, Peter Dalgaard BSA wrote: > > Ross Ihaka <ihaka@stat.auckland.ac.nz> writes: > > > > I played around with this earlier today. There's nothing special about > > dataframes, S does the same with any classed object. I.e. > > > > class(b)<-"my" > > cbind.my<-function(...)match.call() > > > > cbind(a,b) > > > > will dispatch cbind.my > > I played some more. I think data frames are special somehow. > > S> x <- factor(1:10) > S> y <- data.frame(1:10) > > class(x) > [1] "factor" > S> class(y) > [1] "data.frame" > S> class(cbind(x,y)) > [1] "data.frame" > S> class(cbind(y,x)) > [1] "data.frame" > > They seem to overpower other class arguments too.This is because there's no cbind.factor: S> cbind.factor<-function(...) match.call() S> cbind(x,y) x y X1.10 1 numeric, 10 attr(, "names"): [1] "" "X1.10" Warning messages: 1: Incompatible methods ("cbind.factor", "cbind.data.frame") for "cbind" 2: Number of rows of result is not a multiple of vector length (arg 1) in: cbin d(x, y) (and cbind.data.frame just calls data.frame(...) so it's little wonder that the result is always a data frame) -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Ross Ihaka
1999-Aug-07 00:37 UTC
cbind is not generic as claimed, omits labels where S has them (PR#239)
From ripley@stats.ox.ac.uk Sat Aug 7 09:49:12 1999 Date: Fri, 6 Aug 1999 22:49:07 +0100 (GMT Daylight Time) From: Prof Brian D Ripley <ripley@stats.ox.ac.uk> To: Ross Ihaka <ihaka@stat.auckland.ac.nz> cc: r-devel@stat.math.ethz.ch Subject: Re: cbind is not generic as claimed, omits labels where S has them (PR#239) MIME-Version: 1.0 On Sat, 7 Aug 1999, Ross Ihaka wrote: > Ok, I have made some changes to cbind/rbind which will support > dispatch to other methods. As part of this I have changed > things so that the values passed on are packaged up as > (evaluated) promises so that any closure they invoke will > be able to use substitute to get text values Sorry, are you using `closure' to mean `method' in S (and I thought R) terminology? (I thought a function closure involved the environment....) Technicality : I mean interpreted function. I'm disallowing dispatch to functions without at least an interpreted wrapper. I don't think this is a real restriction. > to use as labels. What I need is a clear idea of the rules for doing > the dispatch. The picture I have at present is: > > dispatch.class <- "default" > for (arg in arg.list) { > if (arg is an object) { > arg.class <- class(arg)[1] > if (there is a method for arg.class) { > if (dispatch.class == "default") > class <- arg.class > else if (args.class != dispatch.class) > drop through to dispatch > } > } > } > dispatch: > if (dispatch.class != "default") > dispatch to appropriate closure > else > carry out default actions > > This also looks like it sufficiently generic that it could be packaged > as a useful function along the lines of "DespatchOrEval" -- perhaps > MultiDespatchOrEval. > > Does this sound right? `right', huh? That's hard. I had been thinking about multiple classes, which bedevil all this (and JMC got rid of for that reason, I guess). I think your rules says choose the class of the leading argument whose first class has a method, and I think that is wrong. Suppose my two args both have class c("mts", "ts") and there is no cbind.mts. Then you will dispatch the default, even though the normal rules for dispatching on the first arg would dispatch cbind.ts. I suspect we need to try more than the first method, but have no clear picture of what is right. I would dispatch on the first arg that had a usable method. I think I'm shooting for S compatibility here (I'm firmly in both the compatible and non-compatible camps -- trying to please everyone I guess). I believe Peter described what S3 appears to do, and the above is my interpretation of what he said. I think trying to do inheritance by traversing the class vectors might be asking for trouble. It would certainly be significantly more complex and probably slower. Taking the first arg with a usable method means that cbind(a, b) could be a significantly different class of object from cbind(b, a). This is sometimes a nasty surprise for people. The S3 philosophy seems to be that in cases of conflict you ignore classes entirely. That does give a symmetric result. Ross [ Duncan and I talked about implementing a new kind of object system -- different from either S3 or S4. It would look a little more like Java. Definitely a Version 2 project. ] -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Possibly Parallel Threads
- cbind is not generic as claimed, omits labels where S has them (PR#240)
- cbind is not generic as claimed, omits labels where S has them (PR#241)
- methods cbind2 bind_activation disrupts cbind everywhere
- cbind() & rbind() for S4 objects -- 'Matrix' package changes
- as.data.frame(cbind()) transforming numeric to factor?