[S] Summary of responses

John Warner (jwarner@cscar.umich.edu)
Wed, 29 Apr 1998 14:51:47 -0400


The following is a summary of the responses that I received to my formatting question.
I believe that I also had a response from Brian Ripley which I cannon find at present
(my apologies). Again, thanks to all who replied.

John Warner

My origanal mailing was:

I am having trouble with the cat, format, and round functions. A loop of the
following form

for (i in 1:4) {
x <- kruskal.test(t[,i+2],gp)[[3]]
z1 <- c(med[i,1],med[i,2],med[i,3],med[i,4])
z2 <- c(mn[i,1],mn[i,2],mn[i,3],mn[i,4])
z3 <- c(se[i,1],se[i,2],se[i,3],se[i,4])
cat( "\n",label[i]," Median",format( round(z1,5)),
"\n",blank, " Mean ",format( round(z2,5)),
"\n",blank, " S.E. ",format( round(z3,5)))
}

Produces output as follows

Media Median 0.0010 0.2545 0.1840 0.2510
Mean 0.1582 0.2740 0.2124 0.2100
S.E. 0.16755 0.15842 0.03433 0.01621
BCG Median 0.0010 0.1025 0.2510 0.2510
Mean 0.0928 0.2345 0.2514 0.2278
S.E. 0.16462 0.17260 0.03792 0.01792
hsp_65 Median 0.001 0.202 0.001 0.307
Mean 0.2708 0.2640 0.0766 0.2944
S.E. 0.20541 0.16006 0.02858 0.01663
SEA Median 0.0010 0.3905 0.0850 0.1410
Mean 0.0010 0.4065 0.1236 0.4936
S.E. 0.00000 0.23448 0.01806 0.85485

Can anyone tell me why all of the entries in this table do NOT have the same
number
of digits? What can I do to make these number line up nicely?

Thanks in Advance
John Warner

Replies were as follows
=======================================================================
The problem here is that when you pass format a *row* of your table, it
formats each number in that line to have the same number of decimals
(actually the same field width), and what you want is to have each
*column* to have the same field width. The only way I've been able to
get tables like this to print out the way I want is to use a combination
of paste, format and cat:

labels <- c("Media","BCG","hsp_65","SEA")
b2 <- rep(" ",2)
col1 <- c(label[1],b2,label[2],b2,label[3],b2,label[4],b2)
col2 <- rep(c("Median","Mean","S.E"),4)
numbers <- matrix(0,12,4)

for(i in 1:4){
range <- ((i-1)*3 +1):((i-1)*3 + 3)
for(j in 1:4)
numbers[range,j] <- c(med[i,j],mn[i,j],se[i,j])
}

tbl <- paste(format(col1)," ",format(col2),format(numbers[,1]),
format(numbers[,2]),format(numbers[,3]),format(numbers[,4]))
cat(tbl,fill=max(nchar(tbl)))

To get additional spacing between columns, you can simply place the
appropriate number of blanks in the call to paste (as I've done between
the first two columns).

Once the columns are formatted, an alternative would be to cbind them
together to form a (character) matrix, set the dimnames of the matrix
to appropriate sized vectors of "", and call print with the quote=F
argument.

- Phil Spector
Statistical Computing Facility
Department of Statistics
UC Berkeley
spector@stat.berkeley.edu

========================================================================
They don't ALL have the same number of digits, because you didn't
format them all at once. You could get around this by creating an
array with all the numbers and formatting them before you start the
for loop. For example:

a <- array(dim=c(4, 4, 3))
a[, , 1] <- med
a[, , 2] <- mn
a[, , 3] <- se
fa <- format(round(a, 5))
for (i in 1:4) {
x <- kruskal.test(t[,i+2],gp)[[3]]
cat( "\n", label[i], " Median", fa[i, , 1],
"\n", blank, " Mean ", fa[i, , 2],
"\n", blank, " S.E. ", fa[i, , 3])
}

Hope this helps.

JVA

Try something like this:

for (i in 1:4) {
x <- kruskal.test(t[,i+2],gp)[[3]] # ???
z <- format(round(rbind(0.12345, med[i, 1:4],
mn[i, 1:4], se[i, 1:4]), 5)[-1, ]
cat( "\n",label[i]," Median", z[1, ],
"\n",blank, " Mean ", z[2, ],
"\n",blank, " S.E. ", z[3, ])
}

I would prefer something like the following, myself, though:

options(digits = 5)
for (i in 1:4) {
x <- kruskal.test(t[,i+2],gp)[[3]] # What's this got to do with it ??
z <- rbind(Median = med[i, 1:4],
Mean = mn[i, 1:4],
S.E. = se[i, 1:4])
dimnames(z)[[2]] <- rep("", 4)
cat("\n", label[i])
print(z)
}

-- 
Bill Venables, Head, Dept of Statistics,    Tel.: +61 8 8303 5418
University of Adelaide,                     Fax.: +61 8 8303 3696
South AUSTRALIA.     5005.   Email: Bill.Venables@adelaide.edu.au

=======================================================================

John,

format tries to get away with as few sig figs as it can. Here's a horrible workaround; let me know if you find someting better:

> tmp [1] 0.16750 0.15842 0.03433 0.01621 > format(tmp) # OK [1] "0.16750" "0.15842" "0.03433" "0.01621" > tmp2<-round(tmp,4) > format(round(tmp2,5)) # but we wanted the trailing zeroes [1] "0.1675" "0.1584" "0.0343" "0.0162" > dummy<-0.00001 > format(round(c(tmp2,dummy),5)) [1] "0.16750" "0.15840" "0.03430" "0.01620" "0.00001" > format(round(c(tmp2,dummy),5))[-5] # horrible trick [1] "0.16750" "0.15840" "0.03430" "0.01620"

Nick Nick Ellis CSIRO Marine Research email Nick.Ellis@marine.csiro.au PO Box 120 ph +61 (07) 3826 7260 Cleveland QLD 4163 fax +61 (07) 3826 7222 Australia http://www.marine.csiro.au

=================================================================

I believe that the "nsmall" argument to "format.default" should get you where you want to be. You need at least 3.2 of S-PLUS.

Good luck,

Pat Burns

==========================================================================

John - we have a chapter on table making in the document by Alzola & Harrell on our web page under Stat Computing Tools. -Frank Harrell

--------------------------------------------------------------------------- Frank E Harrell Jr Professor of Biostatistics and Statistics Director, Division of Biostatistics and Epidemiology Dept of Health Evaluation Sciences University of Virginia School of Medicine http://www.med.virginia.edu/medicine/clinical/hes/biostat.htm

====================================================================

When x is a vector of numbers format(x) will produce a vector of character strings, all of the same length (the actual length depends on the values of the numbers). These will neatly line up in a column. So, what you need to do is assemble all of your results, and then format data organized by columns as they will appear in your output (i.e., 4 call to format() rather than the 12 you have).

to see what's going on, experiment with format() a bit. Try format(c(1,2,3)) format(c(1,2,3,1/4)) format(c(1,2,3,1/4,1/3))

An easier way of doing this is probably to construct a dataframe or matrix which holds your results, and then print that.

cheers,

Tony Plate

----------------------------------------------------------------------- This message was distributed by s-news@wubios.wustl.edu. To unsubscribe send e-mail to s-news-request@wubios.wustl.edu with the BODY of the message: unsubscribe s-news