Splus Tips and Links

  1. Line edit mode of Splus...
  2. ...Splus mode of emacs
  3. Running Splus in batch mode
  4. Count elements meeting a condition
  5. Title for multiple graphs
  6. Color graph printing
  7. Fixing functions
  8. Debugging via inspect()
  9. Indirection: variables by text names
  10. Setting up an Splus directory to keep project data separate
  11. Show a sequence of graphs as a "movie"
  12. Using the gamma distribution
  13. Inverse chi square distribution
  14. Random truncated and censored normals
  15. Random multinomial
  16. Random Dirichlet
  17. Interfacing C with Splus
  18. Handling text files with missing values
  19. Keeping track of objects
  20. Losing intermediate results in a "dump"
  21. Multivariate normal random generator
  22. Convert array to dataframe
  23. Change range to midpoint
  24. USA map with states shaded to show a variable
  25. Nicer time plots; Rank, norm, factorial, choose; Gram-Schmidt; Convenience functions
  26. EDA for multi-epoch survival analysis

  1. Are you using editing keys in Splus? If you start Splus with Splus -e, then the editing control sequences are activated. (Try putting alias sp Splus -e in your .cshrc file so you can start Splus in editing mode by just typing Sp.) You can now use the following control characters to edit the current or previous lines: Note: previous line even works after you quit Splus and come back!

  2. A totally different approach to editing in Splus is Emacs S-plus mode.

    To install it, add

       (autoload 'S "/home/CHIMAERA/hseltman/.EmacsS.el" "Starts inferior Splus" t)
       (autoload 'S-mode "/home/CHIMAERA/hseltman/.EmacsS.el" "Mode for editing S source" t)
       
    to your .emacs file in your root directory. Even better, copy the two files to your space, and refer to it there. Once it is installed, when you are in emacs, use Alt-x S<Enter> to start the Splus mode of emacs, and enter the starting directory. Then you can split the screen (Ctrl-x 2) and edit files in one window while running Splus in another.

    From the Splus window's prompt line ("> "), you can use the editing codes listed above to edit your line. Use Alt-P and Alt-N to bring up previous lines for editing. Use Alt-R to search for previous lines to edit.

    One big advantage of Splus mode is that you can get automatic completion of file names and variable names, e.g. read.table("My<Tab> will expand to e.g. read.table("MyFile.S, and ks<Alt-/(a slash)> will expand to ks.gof.

    In S-mode use the form help(nlmin,win=T) for help (or if help.start() is running, just use ?nlmin).

    On the menus, try Help/Describe Mode for more information. The following (edited) section is especially useful:

    Sending code to the S-process
    
       Other commands are also available for evaluating portions of code in
    the S process.  These commands cause the selected code to be evaluated
    directly by the S process as if you had typed them in at the command
    line; the `source()' function is not used.  Note: these commands work
    only if the file containing the code has a .q or .S file name suffix.
    The commands for evaluating
    code are:
    
       * `C-c C-j' (`S-eval-line')
         Send the line containing point to the S process.
    
       * `C-c M-j' (`S-eval-line-and-go')
         As above, but returns you to the S process buffer as well.
    
       * `C-c C-f' or `ESC C-x' (`S-eval-function')
         Send the S function containing point to the S process.
    
       * `C-c M-f' (`S-eval-function-and-go')
         As above, but returns you to the S process buffer as well.
    
       * `C-c C-r' (`S-eval-region')
         Send the text between point and mark to the S process.
    
       * `C-c M-r' (`S-eval-region-and-go')
         As above, but returns you to the S process buffer as well.
    
       * `C-c C-b' (`S-eval-buffer')
         Send the contents of the edit buffer to the S process.
    
       * `C-c M-b' (`S-eval-buffer-and-go')
         As above, but returns you to the S process buffer as well.
    
       * `C-c C-n' (`S-eval-line-and-next-line')
         Sends the current line to the S process, echoing it in the process
         buffer, and moves point to the next line.  Useful when debugging
         for stepping through your code.
    
       It should be stressed once again that these `S-eval-' commands
    should only be used for evaluating small portions of code for debugging
    purposes, or for generating transcripts from source files.  When editing
    S functions, `C-c C-l' is the command to use to update the function's
    value.
    
       One final command is provided for spot-evaluations of S code:
    
         `C-c C-e' (`S-execute-in-tb')
         Prompt for an S expression and evaluate it.  Displays result in a
         temporary buffer.
    
    This is useful for quick calculations, etc.
    
       All the above commands are useful for evaluating small amounts of
    code and observing the results in the process buffer.  A useful way to
    work is to divide the frame into two windows; one containing the source
    code and the other containing the process buffer.
    
    Full documentation and source code for S-mode (Emacs Speaks S)

  3. To run Splus in batch mode, enter your commands into a text file, e.g., mybatch.q. At the unix prompt, type Splus < mybatch.q > myoutput.txt &. You may find it useful to use the unix commands tail mybatch.q, tail -f mybatch.q and/or top to check on the progress of your program. Usually you want to leave off the ampersand if you are writing a c-shell program, because this will assure that the next line is not run until the Splus program finishes.

  4. The quickest way to count the number of vector elements meeting some condition is to use sum() with implicit conversion of logicals to integers. For example:

    Frm3to5_sum(v>=3 & <=5)

  5. To get an overall title on page of multiple graphs, use par(oma=c(2,2,4,2), mfrow=c(r,c)) where r is the number of rows of graphs and c is the number of columns. Sometime after the first graph is drawn and before printing, use mtext("This is my title", outer=T, cex=1.5) to make your title. Experiment with the cex number to control the size of the title lettering.

  6. Color printing requires using postscript(colors=) with an appropriate color matrix. The built in color matrix is ps.colors.rgb which has 734! colors. The low numbers are all whites (invisible), but you can see all of the colors named and numbered in this postscript file. In practice you can make your own color subset or use mine shown here in postscipt which is:
         # My subset has 17 colors: dark black, red, orange, 
         # green, blue, purple, brown
         # and light grey, red, orange, 
         # green, blue, purple, brown plus white.
    
         nice.colors_ps.colors.rgb[c(41,194,457,156,133,340,217,444,
                                     45,196,453,157,370,337,207,433,1),]
         
    You use the colors by adding col=n, where n is 1 to 17 for nice.colors, to any plot command.

    If you want to use X11() to test your plot on screen first, use X11("-xrm 'splus*colors: white black red 2 green 2 blue gray red 2 green 2 blue white'") (this is in my f.X11C() function; see "Setup" below). Once the graph looks OK on the screen, to print it in color, you must first make a postscript file: type dev.copy(device=postscript,file="MyFile.ps",colors=nice.colors), and then dev.off(). An alternative to using ,colors=nice.colors) in each dev.copy() call is to use ps.options(colors=nice.colors) once per S-plus session.
    To use color in motif(), run motif(), then select "Color Scheme..." from the "Options" menu. Click on a scheme, e.g. "Cyan to Red", then click "Apply". (If you get an error message, quit Netscape or other color hogging programs and try again.) Note the order of the colors for "lines", "text" (including plot symbols), etc. Use e.g. ,col=3 in a plotting command to plot in the third color on the list. Or, change some of the colors on the list (be sure to click "Apply" again). To make color postscript files, just use the same dev.copy trick shown above. To directly print color plots, use ps.options.send(colors=xgetrgb(), background=xgetrgb("background")) before using the motif print button.

  7. Do you use fix(MyFunction) to quickly modify a function? If you first execute options(editor="emacs"), you can make your change with "emacs" rather than "vi".

  8. Do you use inspect()? When you can't get your function debugged, try inspect(MyFunc(Arg1,Arg2,etc.)). This will allow you to single step through your code, and print out any intermediate object values to see if they are the values you expected them to be. It is slow, but very powerful. Briefly, you can always type help to see the possible commands. Command step takes you one (often a half) step forward in your program. Command eval SomeObject prints anything, or evaluates any function, including, e.g. plot(). Command mark MyFunction followed by resume runs quickly up to MyFunction(). Function complete finishes a loop. Function quit quits at any time. (Not available for version 5, but back in version 6.)

    For simpler debugging problems, try adding browser() at various points through your program. Then you can evaluate any expressions when the program stops at the browser() lines. Just type the name of a variable or type an expression, and it will be evaluated. You can even type expressions because you are really interested in their side effects, e.g. plot(x,y) or write.table(x) or x=3*y. Type "c" to continue through your function or "stop" to immediately cancel the function.

  9. How can I access a variable by a string with its name? E.g. I want to work with Tmp1, Tmp2, etc. To put the value of e.g. Tmp3$Name into rslt, assuming i=3, I use rslt_eval( parse( text=paste("Tmp", i, "$Name", sep="")). To store the square root of x into Tmp3, I use assign( paste("Tmp", i, sep=""), sqrt(x), where=1). Note that the "where=1" clause is essential for an ordinary assignment.

  10. Setting up a new directory: run Splus CHAPTER in any new directory from which I want to run Splus. This file creates a .Data directory in the current directory which will be empty when you try ls is Splus, and will allow you to keep your data (variables) for a given project separate from all of your other projects. Remember to type options(editor="emacs") the first time you go into Splus if you use the fix() function.
  11. How to make a nice smooth "movie" from a sequence of graphs: If you want a sequence of graphs to play like a movie, but not be jittery, follow this example, which shows different smoothings of a non-parametric curve through random data.
         motif()  # on Linux, only motif plots implement double buffering
         x=seq(1.0,100.0,1.0); y=rnorm(100)
         double.buffer("back")   # plots are drawn invisibly "in the back"
         for (f in seq(0.8, 0.1, -0.05)) {
           plot(x,y,main=paste("f =",f)); lines(lowess(x,y,f=f))
           double.buffer("copy")    # move the "in the back" plot "to the front"
           sleep(1)  # increase the argument for a slower movie
         }
         double.buffer("front")  # return plotting to normal
         
  12. How do I convert Splus's 1 parameter gamma distribution to the 2 parameter gamma distribution? The "rgamma()" function now has a scale parameter.

  13. Need an inverse chi-square random variable? To generate n inverse chi-square rvs with d degrees of freedom and parameter s2, use (s2 * df / 2) / rgamma(n, df / 2).

  14. Need to generate random censored or truncated normals? Censored is trivial, but truncated is trickier (unless you are willing to use the inefficient rejection method). Working functions are in censtrunc.q.

  15. Need to generate a random multinomial? The file multinom.q has the rmultinom() function that generates a single random multinomial given "n" and a vector of probabilities adding to 1.

  16. Need to generate random Dirichlet's? The file dirich.q contains the function rdirich() which generates n Dirichlet's given a vector of parameters (usually called alphas).

  17. How do I interface C with Splus? CallC.html is a bigger example, but using the old style interface.

  18. How do I handle missing values not coded as missing in a text input file? Use my program FixMiss (PC/Linux version here). At the Unix prompt type FixMiss infile outfile where "infile" is a data file with blanks, and outfile is where you want the output written. The program will replace blanks with 'NA'. For SAS use the '/dot' switch to get dots instead of 'NA'. The source code is here if you want to modify it or compile for other than PC/Linux.

  19. How do I keep track of all of my objects? Use the "class=" argument to the "objects()" functions. E.g. to see all of your matrices, type objects(class="matrix"). The other most useful classes are "function" and "data.frame".

  20. What can I do about losing intermediate results when my program aborts? Add a synchronize() command, e.g. at the end of a loop. Variables set before the last synchronize are not lost.

  21. How do I generate multivariate normal data? Splus now has a function called "rmvnorm()" to generate multivariate normals.

  22. How do I convert an array to a dataframe? Use arrtodf(). The array must have dimnames; to add them try something like dimnames(myarray)_list(a=paste("a",1:alen,sep=""), b=paste("b",1:blen,sep=""), c=paste("c",1:clen,sep="")).

  23. How do I convert some ugly range (e.g. a cut() label) to the midpoints? Use midpt, e.g.
     > jnk_cut(runif(50,0,30),6)
     > levels(jnk)
     [1] " 0.2554031+ thru  5.071073" " 5.0710725+ thru  9.886742"
     [3] " 9.8867419+ thru 14.702411" "14.7024114+ thru 19.518081"
     [5] "19.5180808+ thru 24.333750" "24.3337502+ thru 29.149420"
     > levels(jnk)_midpt(jnk,2)
     > levels(jnk)
     [1] "2.66"  "7.48"  "12.29" "17.11" "21.93" "26.74"
     
  24. How do I get a USA map (of the lower 48 states) that shows, by shading, the value of some variable? Source map.q and then use the colormap() function. Instructions are in the file. Briefly, your data must consist of a vector of any variable you want to plot, with the corresponding states names as the names() of your vector or as a separate vector. There must only be one entry per state. DC, PR etc. may be present, but will be ignored. NA's will be reverse hashed. The basic call is simply colormap(values). Use ,mn=# and ,mx=# to set a nice scale range that contains all of your data. Use ,outfile="myfile" to send output directly to a postscript file instead of the screen. Use ,spread=# to set the number of color levels (between each of white, yellow, red and black).

    For color plots on screen (as opposed to directly to a postscript file) X11 is used. A new color device can be opened to compare multiple maps if you use ,new=T. If you want to send the map to the screen and later use dev.copy(postscript,file="myfile.ps");dev.off() to get a postscript version, you should use ,setpscol=T to set the postscript colors to match the screen colors. To make a denser (and slower) rendering of the colors use e.g. density=250.

    For speed, only the states passed to colormap() have outlines. To add outlines for all states, use ,outline=T. If only a few are missing, it is quicker to use, e.g., ,outline=c("New Jersey","Oklahoma").

    For Splus version 5.x, it appears I can't set the colors through my program. You must set them as follows: type motif(). In the graph window choose options, color scheme, create new scheme. Call the scheme, e.g. WYRB10, and set the background to white and the colors for all the other lines to black white c yellow c red c black, where "c" is the "spread" which is 10 by default. Choose apply to make this the current color scheme. Now colormap() will map correctly. Regardless of how you set the motif() colors, the outfile= form of colormap() will produce an appropriately colored postscript file.

    Here is a postscript reference paper on maps in Splus.

  25. How do I get nicer time plots; norm, and choose functions; Gram-Schmidt orthogonalization; and other convenience functions? Source steph.q courtesy of Dr. Stephanie Land.

  26. How do I get nice color plots of several events per subject, with the option to line up on any one event, to sort by any variable or by an inter-event time, and to group by any variable? On Splus version 3 or 4, use SurvEDA.q. Test with SurvEDATest.q

    On Splus 2000, first source SurvEDA.ssc, then source cbSurvEDA.ssc, then source guiSurvEDA.ssc. This will create a "MyStats" menu item that you can use to run SurvEDA. Among other features, the last plot parameters will be memorized and appear as the defaults when you re-run the command, you can specify the maximum number of subjects per plot, you can specify colors visually, and multiple plots appear as "pages" that you can flip between.


Useful S-plus Links


All links active 5/25/2006. Please report missing links to


up To my Home Page