The documentation for ftable
tells us that "ftable
creates ‘flat’ contingency tables". However, the meaning of this isn't getting through to me. I've placed two examples below, but they look so similar that I feel like I'm completely missing the distinction between table
and ftable
. Am I ignorant of some critical programming or statistical idea?
> ftable(mtcars[c("cyl", "vs", "am", "gear")])
gear 3 4 5
cyl vs am
4 0 0 0 0 0
1 0 0 1
1 0 1 2 0
1 0 6 1
6 0 0 0 0 0
1 0 2 1
1 0 2 2 0
1 0 0 0
8 0 0 12 0 0
1 0 0 2
1 0 0 0 0
1 0 0 0
> table(mtcars[c("cyl", "vs", "am", "gear")])
, , am = 0, gear = 3
vs
cyl 0 1
4 0 1
6 0 2
8 12 0
, , am = 1, gear = 3
vs
cyl 0 1
4 0 0
6 0 0
8 0 0
, , am = 0, gear = 4
vs
cyl 0 1
4 0 2
6 0 2
8 0 0
, , am = 1, gear = 4
vs
cyl 0 1
4 0 6
6 2 0
8 0 0
, , am = 0, gear = 5
vs
cyl 0 1
4 0 0
6 0 0
8 0 0
, , am = 1, gear = 5
vs
cyl 0 1
4 1 1
6 1 0
8 2 0
My suspicion is that it means "flat" as in "flattern a nested list", but if that was the case, then I'm not sure why I cannot feed exactly the same arguments to ftable
as I can table
. For example, ftable(Titanic, row.vars = 1:3)
is valid, but table(Titanic, row.vars = 1:3)
throws an error about the arguments having non-equal lengths.
If we look at the structure, it is evident from the dim
attributes
tbl1 <- table(mtcars[c("cyl", "vs", "am", "gear")])
str(tbl1)
'table' int [1:3, 1:2, 1:2, 1:3] 0 0 12 1 2 0 0 0 0 0 ...
- attr(*, "dimnames")=List of 4
..$ cyl : chr [1:3] "4" "6" "8"
..$ vs : chr [1:2] "0" "1"
..$ am : chr [1:2] "0" "1"
..$ gear: chr [1:3] "3" "4" "5"
ftbl1 <- ftable(mtcars[c("cyl", "vs", "am", "gear")])
str(ftbl1)
'ftable' int [1:12, 1:3] 0 0 1 0 0 0 2 0 12 0 ...
- attr(*, "row.vars")=List of 3
..$ cyl: chr [1:3] "4" "6" "8"
..$ vs : chr [1:2] "0" "1"
..$ am : chr [1:2] "0" "1"
- attr(*, "col.vars")=List of 1
..$ gear: chr [1:3] "3" "4" "5"
i.e. flat table is 2D, while the table
is a 4D array
dim(tbl1)
#[1] 3 2 2 3
dim(ftbl1)
#[1] 12 3
Note that both of them are array
s, and an array
is also a vector
with some dim
attributes.
Both are not list
s. It is the attributes that make them different and how they are arranged. e.g. if we remove the attributes, they are just vector
s arranged in different order of values
c(ftbl1)
#[1] 0 0 1 0 0 0 2 0 12 0 0 0 0 0 2 6 0 2 2 0 0 0 0 0 0 1 0 1 0 1 0 0 0 2 0 0
c(tbl1)
#[1] 0 0 12 1 2 0 0 0 0 0 0 0 0 0 0 2 2 0 0 2 0 6 0 0 0 0 0 0 0 0 1 1 2 1 0 0
Check if it is a list
is.list(tbl1)
#[1] FALSE
is.list(ftbl1)
#[1] FALSE
Regarding the error in table
, it is just that it doesn't have the row.vars
argument if we check the ?table
table(..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no", "ifany", "always"), dnn = list.names(...), deparse.level = 1)
whereas ?ftable
ftable(..., exclude = c(NA, NaN), row.vars = NULL, col.vars = NULL)