on 03/02/2009 03:11 PM Max Kuhn wrote: > PJ, > >> Hi, I've been trying to prepare some crosstables for some survey questions >> for a client. I have been using the CrossTable function in the gmodels >> package. However, this command only seems to be able to create CrossTables >> in text documents. >> >> I've been trying to use odfTable in odfweave to create tables that are >> standalone objects in the document that I can then convert to other formats, >> copy and paste and do whatever with. > > You will have to do some work to get CrossTable results into odfWeave > for a few reasons. The main one is: CrossTable prints the output (as > opposed to outputting an object of a certain class that uses print to > make the results like table() and print.table()). In some cases, it is > easy to translate the output you see on the screen to odf markup. I'm > not sure that this function is one of those cases. That is not a > slight against the function, it just isn't meant to do that. > >> The problem is no matter how I try to get the CrossTable into the odfTable, >> i either get an error message saying there is no appropriate method for >> odfTable or the table is inproperly formatted. > > It would be nice to have a reproducible example along with the results > of sessionInfo(). Looking at ?odfTable, it has that the main argument > should be "a vector, matrix or data frame". I can' tell if there is a > bug in odfTable or if you are just using it incorrectly. > >> Honestly, I'm not even married to using odfTable. All I'm looking for is a >> nicely formatted table, that is a standalone object, that I can copy and >> paste and convert at will, and that contains the column percentages in the >> table. > > CrossTable may not be what you want then. The results are a list of > components of the table.
In follow up to Max' post, if you can output or print the captured CrossTable() content in odfWeave to a monospaced font, it would line up appropriately. The use of a monospace font in the R console is the presumption for CrossTable() output. However, it will look exactly as it would in the R console (see below) as opposed to something more formalized and "pretty". You could largely recreate most of CrossTable's output using table() and prop.table() by creating a matrix or dataframe, depending upon what you want things to look like. This is what is essentially done within CrossTable(). Using one of the examples in ?CrossTable: > CrossTable(infert$education, infert$induced, prop.chisq = FALSE) ... | infert$induced infert$education | 0 | 1 | 2 | Row Total | -----------------|-----------|-----------|-----------|-----------| 0-5yrs | 4 | 2 | 6 | 12 | | 0.333 | 0.167 | 0.500 | 0.048 | | 0.028 | 0.029 | 0.162 | | | 0.016 | 0.008 | 0.024 | | -----------------|-----------|-----------|-----------|-----------| 6-11yrs | 78 | 27 | 15 | 120 | | 0.650 | 0.225 | 0.125 | 0.484 | | 0.545 | 0.397 | 0.405 | | | 0.315 | 0.109 | 0.060 | | -----------------|-----------|-----------|-----------|-----------| 12+ yrs | 61 | 39 | 16 | 116 | | 0.526 | 0.336 | 0.138 | 0.468 | | 0.427 | 0.574 | 0.432 | | | 0.246 | 0.157 | 0.065 | | -----------------|-----------|-----------|-----------|-----------| Column Total | 143 | 68 | 37 | 248 | | 0.577 | 0.274 | 0.149 | | -----------------|-----------|-----------|-----------|-----------| # Do the above incrementally # Generate counts and proportions # row, column and table TAB <- table(infert$education, infert$induced) TAB.prop.r <- prop.table(table(infert$education, infert$induced), 1) TAB.prop.c <- prop.table(table(infert$education, infert$induced), 2) TAB.prop.t <- prop.table(table(infert$education, infert$induced)) # rbind() it all together MAT <- rbind(TAB, TAB.prop.r, TAB.prop.c, TAB.prop.t) # order by rownames MAT <- MAT[order(rownames(MAT)), ] # Set duplicated rownames to blank rownames(MAT)[which(duplicated(rownames(MAT)))] <- "" > MAT 0 1 2 0-5yrs 4.00000000 2.000000000 6.00000000 0.33333333 0.166666667 0.50000000 0.02797203 0.029411765 0.16216216 0.01612903 0.008064516 0.02419355 12+ yrs 61.00000000 39.000000000 16.00000000 0.52586207 0.336206897 0.13793103 0.42657343 0.573529412 0.43243243 0.24596774 0.157258065 0.06451613 6-11yrs 78.00000000 27.000000000 15.00000000 0.65000000 0.225000000 0.12500000 0.54545455 0.397058824 0.40540541 0.31451613 0.108870968 0.06048387 So that gives you the core table with counts, table, row and column proportions in that order top to bottom for each row category as in CrossTable(). Adjust the above based upon what you actually want in the table output. With some additional work, you could add row and column totals and so forth. If you wanted variable numbers of digits after the decimal for each row as in CrossTable(), you could pre-format the numbers using sprintf(), converting MAT to a character matrix in the process. For example: MAT.3 <- t(apply(rbind(TAB.prop.r, TAB.prop.c, TAB.prop.t), 1, function(x) sprintf("%.3f", x))) MAT <- rbind(TAB, MAT.3) # order by rownames MAT <- MAT[order(rownames(MAT)), ] # Set duplicated rownames to blank rownames(MAT)[which(duplicated(rownames(MAT)))] <- "" > MAT 0 1 2 0-5yrs "4" "2" "6" "0.333" "0.167" "0.500" "0.028" "0.029" "0.162" "0.016" "0.008" "0.024" 12+ yrs "61" "39" "16" "0.526" "0.336" "0.138" "0.427" "0.574" "0.432" "0.246" "0.157" "0.065" 6-11yrs "78" "27" "15" "0.650" "0.225" "0.125" "0.545" "0.397" "0.405" "0.315" "0.109" "0.060" With 'MAT' finalized, you could then use Max' functions to generate pretty output for an OO.org document or use xtable() in the xtable package or latex() in the Hmisc package for LaTeX or perhaps HTML output. HTH, Marc Schwartz ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.