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
|