Skip to content
Prev 172316 / 398502 Next

Cross Tables with odfTable in odfweave

on 03/02/2009 03:11 PM Max Kuhn wrote:
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:
...

                 | 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)))] <- ""
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)))] <- ""
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