Hi I am writing a bunch of functions that take two, three or four arguments. These functions operate on vectors of the same length; but I want the function to behave sensibly if one or more arguments are scalars. "+" does this for two arguments: "+"(1:10,3) # interpreted as "+"(1:10,rep(3,10)) But my functions can take more arguments. Say f() takes three: f(1:10,1:10,1:10) # default f(3,1:10,1:10) # interpret as f(rep(3,10),1:10,1:10) f(1:10,3,1:10) # interpret as f(1:10,rep(3,10),1:10) f(1:10,3,5) # interpret as f(1:10,rep(3,10),rep(5,10)) and h() takes four: h(2,4,5,1:10) # interpret as h(rep(2,10),rep(4,10),rep(5,10),1:10) h(2,3,1:10,1) # interpret as h(rep(2,10),rep(3,10),1:10,rep(1:10) h(1:20,3,1:20,1) # interpret as h(1:20,rep(3,20),1:20,rep(1,20)) I haven't got any that need five yet, but this may change in the future. How do I implement this desired behaviour nicely? (I pass the arguments to .C(), which is why I need this). -- Robin Hankin Uncertainty Analyst Southampton Oceanography Centre SO14 3ZH tel +44(0)23-8059-7743 initialDOTsurname at soc.soton.ac.uk (edit in obvious way; spam precaution)
I think you should implement recycling, ideally at C level. But you could have f <- function(x, y, z) { n <- max(length(x), length(y), length(z)) .C("something", as.double(rep(x, len=n)), as.double(rep(y, len=n)), as.double(rep(z, len=n)), as.integer(n), ans)$ans } On Mon, 15 Nov 2004, Robin Hankin wrote:> > Hi > > I am writing a bunch of functions that take two, three or four > arguments. These functions operate on vectors of the same length; but I > want the function > to behave sensibly if one or more arguments are scalars. "+" does this for > two arguments: > > > "+"(1:10,3) # interpreted as "+"(1:10,rep(3,10)) > > But my functions can take more arguments. Say f() takes three: > > f(1:10,1:10,1:10) # default > f(3,1:10,1:10) # interpret as f(rep(3,10),1:10,1:10) > f(1:10,3,1:10) # interpret as f(1:10,rep(3,10),1:10) > f(1:10,3,5) # interpret as f(1:10,rep(3,10),rep(5,10)) > > and h() takes four: > > h(2,4,5,1:10) # interpret as h(rep(2,10),rep(4,10),rep(5,10),1:10) > h(2,3,1:10,1) # interpret as h(rep(2,10),rep(3,10),1:10,rep(1:10) > h(1:20,3,1:20,1) # interpret as h(1:20,rep(3,20),1:20,rep(1,20)) > > I haven't got any that need five yet, but this may change in the future. > How do I implement this desired behaviour nicely? > > (I pass the arguments to .C(), which is why I need this). > > -- > Robin Hankin > Uncertainty Analyst > Southampton Oceanography Centre > SO14 3ZH > tel +44(0)23-8059-7743 > initialDOTsurname at soc.soton.ac.uk (edit in obvious way; spam precaution) > > ______________________________________________ > R-help at 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 > >-- Brian D. Ripley, ripley at 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
> I think you should implement recycling, ideally at C level.> But you could have > > f <- function(x, y, z) > { > n <- max(length(x), length(y), length(z)) > .C("something", as.double(rep(x, len=n)), as.double(rep(y, len=n)), > as.double(rep(z, len=n)), as.integer(n), ans)$ans > } yes! this works exactly as desired. Thank you. Another thing that is incidentally satisfied by this scheme is to preserve attributes such as dimensions and dimnames. It seems to me to make sense to use the attributes of the longest argument, and then set them after the call to wit f <- function(x, y, z) { lens <- c(length(x), length(y), length(z)) all.attributes <- list(attributes(x),attributes(y),attributes(z)) n <- max(lens) attributes.desired <- all.attributes[[which.max(lens)]] .C("something", as.double(rep(x, len=n)), as.double(rep(y, len=n)), as.double(rep(z, len=n)), as.integer(n), ans)$ans attributes(ans) <- attributes.desired return(ans) } Is this good practice? best wishes rksh> > > > On Mon, 15 Nov 2004, Robin Hankin wrote: > > > > Hi > > I am writing a bunch of functions that take two, three or four > arguments. These functions operate on vectors of the same length; but > I want the function > to behave sensibly if one or more arguments are scalars-- Robin Hankin Uncertainty Analyst Southampton Oceanography Centre SO14 3ZH tel +44(0)23-8059-7743 initialDOTsurname at soc.soton.ac.uk (edit in obvious way; spam precaution)