Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,
This is as doumented, and I think you could say the same thing of seq(). BTW, sequence() allows negative inputs, and I don't think you want sum(input) in that case. I've never seen the point of sequence(), but it has been around in R for a long time. It is used in packages eRm, extRemes, hydrosanity, klaR, seas. Who knows what people have in private code, so I don't see any compelling case to change it. If people want a different version, it would only take a minute to write (see below). We could make seq_len take a vector argument, but as you point out in a followup that makes it slower in the common case. It also changes its meaning if a length > 1 vector is supplied, and would speed matter in the long-vector case? What does sequence0 <- function (nvec) { s <- integer(0) for (i in nvec) s <- c(s, seq_len(i)) s } not do that is more than a very rare need? On Thu, 26 Jul 2007, [EMAIL PROTECTED] wrote: > Full_Name: Bill Dunlap > Version: 2.5.0 > OS: Linux > Submission from: (NULL) (70.98.76.47) > > > sequence(nvec) is documented to return > the concatenation of seq(nvec[i]), for > i in seq(along=nvec). This produces inconvenient > (for me) results for 0 inputs. >> sequence(c(2,0,3)) # would like 1 2 1 2 3, ignore 0 >[1] 1 2 1 0 1 2 3 > Would changing sequence(nvec) to use seq_len(nvec[i]) > instead of the current 1:nvec[i] break much existing code? > > On the other hand, almost no one seems to use sequence() > and it might make more sense to allow seq_len() and seq() > to accept a vector for length.out and they would return a > vector of length sum(length.out), >c(seq_len(length.out[1]), seq_len(length.out[2]), ...) > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] sweep sanity checking?
When I was preparing the patch of sweep submitted on July 25, I was unaware of the code by Heather Turner. She suggested a very elegant solution, if STATS is a vector and we want to use meaningful recycling in full generality. I would like to suggest a combined solution, which uses Heather Turner's algorithm if check.margin=FALSE (default) and STATS is a vector and my previous algorithm, if check.margin=TRUE or STATS is an array. The suggestion is # combined from the original code of sweep without warnings and from # https://stat.ethz.ch/pipermail/r-help/2005-June/073989.html by Robin Hankin # https://stat.ethz.ch/pipermail/r-help/2005-June/074001.html by Heather Turner # https://stat.ethz.ch/pipermail/r-devel/2007-June/046217.html by Ben Bolker # with some further modifications by Petr Savicky sweep <- function(x, MARGIN, STATS, FUN = "-", check.margin=FALSE, ...) { FUN <- match.fun(FUN) dims <- dim(x) dimmargin <- dims[MARGIN] if (is.null(dim(STATS))) { dimstats <- length(STATS) } else { dimstats <- dim(STATS) check.margin <- TRUE } s <- length(STATS) if (s > prod(dimmargin)) { warning("length of STATS greater than the extent of dim(x)[MARGIN]") } else if (check.margin) { dimmargin <- dimmargin[dimmargin > 1] dimstats <- dimstats[dimstats > 1] if (length(dimstats) > length(dimmargin) || any(dimstats != dimmargin[seq(along.with=dimstats)])) warning("length(STATS) or dim(STATS) do not match dim(x)[MARGIN]") } else { cumDim <- c(1, cumprod(dimmargin)) upper <- min(cumDim[cumDim >= s]) lower <- max(cumDim[cumDim <= s]) if (upper %% s != 0 || s %% lower != 0) warning("STATS does not recycle exactly across MARGIN") } perm <- c(MARGIN, (1:length(dims))[ - MARGIN]) FUN(x, aperm(array(STATS, dims[perm]), order(perm)), ...) } Heather presented four examples testing her code: sweep(array(1:24, dim = c(4,3,2)), 1, 1:2)# no warning sweep(array(1:24, dim = c(4,3,2)), 1, 1:12) # no warning sweep(array(1:24, dim = c(4,3,2)), 1, 1:24) # no warning sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:3) # warning The second and third example are not really correct, since STATS extends also to dimensions not included in MARGIN. The problem is better visible for example in sweep(array(1:24, dim = c(4,4,3,3,2,2)), c(1,3), 1:12) where MARGIN clearly has to contain two dimensions explicitly. So, I use the examples with a larger margin corresponding to STATS as follows sweep(array(1:24, dim = c(4,3,2)), 1, 1:2)# no warning sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:12) # no warning sweep(array(1:24, dim = c(4,3,2)), 1:3, 1:24) # no warning sweep(array(1:24, dim = c(4,3,2)), 1:2, 1:3) # warning The current proposal for sweep indeed gives no warning in the first three examples and gives a warning in the last one. I did not use the suggestion to call the option warn with default warn = getOption("warn"). The reason is that there are two different decisions: (1) whether to generate a warning (2) what to do with the warning, if it is generated. The warn option influences (2): the warning may be suppressed, printed after the return to the top level, printed immediately or it may be converted to an error. I think that the option controling (2) should not be mixed with an option which controls (1). If R has an option controling to which extent recycling is allowed, then this could be used, but warn has a different purpose. I appreciate feedback. Petr. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,
On 27 Jul 2007, at 08:07, [EMAIL PROTECTED] wrote: > This is as doumented, and I think you could say the same thing of > seq(). > BTW, sequence() allows negative inputs, and I don't think you want > sum(input) in that case. > > I've never seen the point of sequence(), but it has been around in > R for a > long time. It is used in packages eRm, extRemes, hydrosanity, > klaR, seas. > Who knows what people have in private code, so I don't see any > compelling > case to change it. If people want a different version, it would > only take > a minute to write (see below). > > We could make seq_len take a vector argument, but as you point out > in a > followup that makes it slower in the common case. It also changes its > meaning if a length > 1 vector is supplied, and would speed matter > in the > long-vector case? What does > > sequence0 <- function (nvec) > { > s <- integer(0) > for (i in nvec) s <- c(s, seq_len(i)) > s > } > > not do that is more than a very rare need? > My 2 cents: Defining mySequence <- function(x){unlist(sapply(x,function(i){seq_len (i)}))} is much faster. Neither sequence0() nor mySequence() accepts vectors with any element <0 although as Brian Ripley points out, sequence() itself does (which I think is undesirable). Robin Hankin Uncertainty Analyst National Oceanography Centre, Southampton European Way, Southampton SO14 3ZH, UK tel 023-8059-7743 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Rd2dvi (PR#9812)
It seems this feature was introduced in Perl 5.6.1, but that is older than Solaris 9 (which was first released 9/02 according to www.sun.com). We need to know what version of Perl this was. On Thu, 26 Jul 2007, Bill Dunlap wrote: > On Thu, 26 Jul 2007 [EMAIL PROTECTED] wrote: > >> Is this a bug-- >> >> --- >> <234>% R CMD Rd2dvi base.Rd >> Converting Rd files to LaTeX ... >> base.Rd >> Can't use an undefined value as filehandle reference at >> /opt/R-2.5.1/lib/R/share/perl/R/Rdconv.pm line 78. > > This may be due to a change I suggested a while back which > required perl 5.6 (or so) to work. The change was to ensure > that the file handle rdfile was closed when Rdconv was done > with it. If this is the problem, upgrading perl to 5.8 will > make it go away. Rdconv.pm should have a 'use v5.6' (or 5.8?) > line at the top if it wants to continue to use this syntax. > > < open(rdfile, "<$Rdname") or die "Rdconv(): Couldn't open '$Rdfile': > $!\n"; > < > --- >> open(my $rdfile, "<$Rdname") or die "Rdconv(): Couldn't open '$Rdfile': >> $!\n"; >> # Before we added the 'my $' in front of rdfile, >> # rdfile was not getting closed. Now it will close >> # when $rdfile goes out of scope. (We could have added >> # a close rdfile at the end of the while(), but >> # scoping method is more reliable. > 123c127 > < while(){ > --- >> while(<$rdfile>){ > > > Bill Dunlap > Insightful Corporation > bill at insightful dot com > 360-428-8146 > > "All statements in this message represent the opinions of the author and do > not necessarily reflect Insightful Corporation policy or position." > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > -- Brian D. Ripley, [EMAIL PROTECTED] 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, UKFax: +44 1865 272595 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] (PR#9811) sequence(c(2, 0, 3)) produces surprising results,
> "Robin" == Robin Hankin <[EMAIL PROTECTED]> > on Fri, 27 Jul 2007 08:33:18 +0100 writes: Robin> On 27 Jul 2007, at 08:07, [EMAIL PROTECTED] Robin> wrote: >> This is as doumented, and I think you could say the same >> thing of seq(). BTW, sequence() allows negative inputs, >> and I don't think you want sum(input) in that case. >> >> I've never seen the point of sequence(), but it has been >> around in R for a long time. It is used in packages eRm, >> extRemes, hydrosanity, klaR, seas. Who knows what people >> have in private code, so I don't see any compelling case >> to change it. If people want a different version, it >> would only take a minute to write (see below). >> >> We could make seq_len take a vector argument, but as you >> point out in a followup that makes it slower in the >> common case. It also changes its meaning if a length > 1 >> vector is supplied, and would speed matter in the >> long-vector case? What does >> >> sequence0 <- function (nvec) { s <- integer(0) for (i in >> nvec) s <- c(s, seq_len(i)) s } >> >> not do that is more than a very rare need? >> Robin> My 2 cents: Robin> Defining Robin> mySequence <- Robin> function(x){unlist(sapply(x,function(i){seq_len(i)}))} Robin> is much faster. Robin> Neither sequence0() nor mySequence() accepts vectors Robin> with any element <0 although as Brian Ripley points Robin> out, sequence() itself does (which I think is Robin> undesirable). Yes, I agree. Some more historical perspective (Brian alluded to) : As the third R core member (first after Robert & Ross), I still have access to the following R version {on one very old fortunately still running Solaris machine; I'm pretty sure it would not compile anymore on any recent OS/compiler suite} : -- ..$ R-0.00alpha R Alpha-Test Version, Copyright (C) 1995 Robert Gentleman and Ross Ihaka R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type `license()' for details. > sequence function (nvec) { sequence <- NULL for (i in (1:length(nvec))) sequence <- c(sequence, seq(nvec[i])) sequence } > -- which interestingly also "works" for negative nvec[i], but the way it is written even more clearly suggests that negative nvec entries were not the intent. I'm voting that R should adopt a new (fast, but R code only) version of sequence() which gives an error for negative 'nvec' entries --- though I do agree with Brian that it's not really an important function at all. Martin Maechler, ETH Zurich PS: Note that this was before R became GPL'ed "Free software", and that the R version stems from the following place -- back in 1995 : /[EMAIL PROTECTED]:/pub/R/unix/ -rw-r--r-- 1 51 1371 Jun 20 1995 INSTALL -rw-r--r-- 1 51 466232 Jun 20 1995 R-unix-src.tar.gz -rw-r--r-- 1 51 1079 Jun 20 1995 README __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Using R_MakeExternalPtr
As others as commented, everything going in/out of the .Call() interface needs to be SEXP (even if it does nothing and you are returning R_NilValue). Secondly, your attached code is both (1) too long, and (2) incomplete. You should write some *simple* R code that uses only soamInit() and soamUnInit() (the latter is missing and you had not included it), Then fill the middle with soamSubmit(). Nobody really want to read your 60+ line of R code (too long) and incomplete C code (too short) to work out what's broken. Use complete and short examples to illustrate your problem! Also, you seem to take for granted that the typo/length of Argument in soamSubmit() are those you think they are... e.g. I would put in say, for example: if ((JobID == R_NilValue) || ( TYPEOF(JobID) != INTSXP)) { Rprintf("JobID unexpected!\n"); return R_NilValue; } Just to be on the safe side. You may find some surprises there - trying to do INTEGER() on a REALSXP, or vice versa can be dangerous. I am still not convinced that your segfault is to do with externalptr - e.g. the '.Call() must return SEXP' is a basic R extension usage and you didn't understand that one. Jonathan Zhou wrote: > Hi all, > > Here is the R code function in where I called the two C++ and further below > are the 2 C++ functions I used to create the externalptr and use it : > > soam.Rapply <- function (x, func, ..., >join.method=cbind, >njobs, >batch.size=100, >packages=NULL, >savelist=NULL) > { > if(missing(njobs)) > njobs <- max(1,ceiling(nrow(x)/batch.size)) > > if(!is.matrix(x) && !is.data.frame(x)) > stop("x must be a matrix or data frame") > > if(njobs>1) > {rowSet <- lapply(splitIndices(nrow(x), njobs), function(i) x[i, , > drop = FALSE])} else {rowSet <- list(x)} > > sesCon <- .Call("soamInit") > > script <- " " > > fname <- tempfile(pattern = "Rsoam_data", tmpdir = getwd()) > file(fname, open="w+") > if(!is.null(savelist)) { > dump(savelist, fname) > script<-readLines(fname) > } > > if(!is.null(packages)) > for(counter in 1:length(packages)) > { > temp<-call("library", packages[counter], character.only=TRUE) > dput(temp, fname) > pack.call<-readLines(fname) > script<-append(script, pack.call) > } > > for(counter in 1:njobs) > { > caller <- paste("caller", counter, sep = "") > soam.call<-call("dput", call("apply", X=rowSet[[counter]], MARGIN=1, > FUN=func), caller) > dput(soam.call, fname) > soam.call<-readLines(fname) > > temp<-append(script, soam.call) > final.script = temp[1] > for(count in 2:length(temp)){ > final.script<-paste(final.script, temp[count], "\n")} > > .Call("soamSubmit", counter, sesCon, final.script, packages) > } > > .Call("soamGetResults", sesCon, njobs, join.method, parent.frame()) > > for(job in 1:njobs) > { > caller <- paste("result", job, sep = "") > temp = dget(caller) > if(job==1) {retval=temp} else {retval=join.method(retval,temp)} > } > > .Call("soamUninit") > > retval > } > > *** Here are the 2 C++ functions: > > extern "C" > { > SEXP soamInit () > { > // Initialize the API > SoamFactory::initialize(); > > // Set up application specific information to be supplied to Symphony > char appName[] = "SampleAppCPP"; > > // Set up application authentication information using the default > security provider > DefaultSecurityCallback securityCB("Guest", "Guest"); > > // Connect to the specified application > ConnectionPtr conPtr = SoamFactory::connect(appName, &securityCB); > > // Set up session creation attributes > SessionCreationAttributes attributes; > attributes.setSessionName("mySession"); > attributes.setSessionType("ShortRunningTasks"); > attributes.setSessionFlags(SF_RECEIVE_SYNC); > > // Create a synchronous session > Session* sesPtr = conPtr->createSession(attributes); > > SEXP out = R_MakeExternalPtr((void*)temp, R_NilValue, R_NilValue); > > return out; > } > } > > extern "C" > { > void soamSubmit (SEXP jobID,//job ID >SEXP sesCon, //session pointer >SEXP caller, //objects >SEXP pack) //packages > { > char* savelist = CHAR(STRING_ELT(caller, 0)); > string strTemp = ""; > int job = INTEGER(jobID)[0]; > > void* temp = R_ExternalPtrAddr(sesCon); > Session* sesPtr = reinterpret_cast(temp); > > // Create a message > MyMessage inMsg(job, /*pack,*/ savelist); > > // Send it > TaskInputHandlePtr input = sesPtr->sendTaskInput(&inMsg); > } > } _