user2711915 - 1 year ago 65
R Question

# Flatten contingency table in R

I have a contingency table, eg the built in Titanic dataset, and I want a way to drop a variable and merge all the values together. Sort of project the data down onto the lower dimensional space.

e.g. Just looking at one 2-d slice of the table

``````      Sex
Class  Male Female
1st    57    140
2nd    14     80
3rd    75     76
Crew  192     20
``````

If we were to drop the Sex variable, I would want to end up with a 1-d contingency table that looked like:

``````Class  Freq
1st   197
2nd    94
3rd   151
Crew  212
``````

My actual use case is an N dimensional table that I want to be able to construct all N 1-way and N*(N-1)/2 2-way tables from. It feels like there should be a simple way to get this to work.

EDIT: Note that this is not a duplicate of the question this has been linked with, as that is referring to data tables, not contingency tables. The solution here is to convert the contingency table to a data table, then use xtabs to get back to a contingency table. The referenced solution only deals with the case of starting with a data table and wanting to end up with a data table.

``````data(Titanic)
library(dplyr)

as.data.frame(Titanic) %>% group_by(Class) %>% summarise(n=sum(Freq))

# Class     n
# (fctr) (dbl)
# 1    1st   325
# 2    2nd   285
# 3    3rd   706
# 4   Crew   885
``````

or data.table:

``````library(data.table)
as.data.table(Titanic)[, .(n = sum(N)), keyby=Class]
``````

you can make a vector of dim names and then loop over `get(dimname)` in dplyr or data.table to do 1-way or 2-way freqs.

example:

``````dims <- c('Class','Sex','Age')
dt <- as.data.table(Titanic)
for(dim in dims)
print(dt[, .(n = sum(N)), keyby = get(dim)])
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download