In R's sprintf() if any of the arguments has length 0 the function aborts. E.g.,
> sprintf("%d", integer(0)) Error in sprintf("%d", integer(0)) : zero-length argument > sprintf(character(), integer(0)) Error in sprintf(character(), integer(0)) : 'fmt' is not a non-empty character vector This comes up in code like x[nchar(x)==0] <- sprintf("No. %d", seq_along(x)[nchar(x)==0]) which works if x contains any empty strings x<-c("One","Two","") # changes "" -> "No. 3" but not if it doesn't x<-c("One","Two","Three") # throws error instead of doing nothing When I wrote S+'s sprintf() I had it act like the binary arithmetic operators, returning a zero long result if any argument were zero long. (Otherwise its result is as long as the longest input.) I think it would be nice if R's sprintf did this also. Currently you must add defensive code (if (any(nchar(x)==0))...) to make functions using sprintf to work in all cases and that muddies up the code and slows things down. Do you think this is a reasonable thing to do? I've attached a possible patch to src/main/sprintf.c makes the examples above return character(0). Bill Dunlap TIBCO Software Inc - Spotfire Division wdunlap tibco.com ------------------------------------------------------------------- Index: sprintf.c =================================================================== --- sprintf.c (revision 48148) +++ sprintf.c (working copy) @@ -79,13 +79,13 @@ static R_StringBuffer outbuff = {NULL, 0, MAXELTSIZE}; Rboolean use_UTF8; - outputString = R_AllocStringBuffer(0, &outbuff); - /* grab the format string */ nargs = length(args); format = CAR(args); - if (!isString(format) || length(format) == 0) + if (!isString(format)) error(_("'fmt' is not a non-empty character vector")); + if (length(format) == 0) + return allocVector(STRSXP, 0) ; args = CDR(args); nargs--; if(nargs >= 100) error(_("only 100 arguments are allowed")); @@ -97,9 +97,12 @@ for(i = 0; i < nargs; i++) { lens[i] = length(a[i]); if(lens[i] == 0) - error(_("zero-length argument")); + return allocVector(STRSXP, 0) ; if(maxlen < lens[i]) maxlen = lens[i]; } + + outputString = R_AllocStringBuffer(0, &outbuff); + if(maxlen % length(format)) error(_("arguments cannot be recycled to the same length")); for(i = 0; i < nargs; i++)
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel