Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

How to convert a table to a data frame

Writer Andrew Henderson

I have a table in R that has str() of this:

 table [1:3, 1:4] 0.166 0.319 0.457 0.261 0.248 ... - attr(*, "dimnames")=List of 2 ..$ x: chr [1:3] "Metro >=1 million" "Metro <1 million" "Non-Metro Counties" ..$ y: chr [1:4] "q1" "q2" "q3" "q4"

And looks like this when I print it:

 y
x q1 q2 q3 q4 Metro >=1 million 0.1663567 0.2612212 0.2670441 0.3053781 Metro <1 million 0.3192857 0.2480012 0.2341030 0.1986102 Non-Metro Counties 0.4570341 0.2044960 0.2121102 0.1263597

I want to get rid of the x and y and convert it to a data frame that looks exactly the same as the above (three rows, four columns), but without the x or y. If I use as.data.frame(mytable), instead I get this:

 x y Freq
1 Metro >=1 million q1 0.1663567
2 Metro <1 million q1 0.3192857
3 Non-Metro Counties q1 0.4570341
4 Metro >=1 million q2 0.2612212
5 Metro <1 million q2 0.2480012
6 Non-Metro Counties q2 0.2044960
7 Metro >=1 million q3 0.2670441
8 Metro <1 million q3 0.2341030
9 Non-Metro Counties q3 0.2121102
10 Metro >=1 million q4 0.3053781
11 Metro <1 million q4 0.1986102
12 Non-Metro Counties q4 0.1263597

I probably fundamentally do not understand how tables relate to data frames.

2

5 Answers

I figured it out already:

as.data.frame.matrix(mytable) 

does what I need -- apparently, the table needs to somehow be converted to a matrix in order to be appropriately translated into a data frame. I found more details on this as.data.frame.matrix() function for contingency tables at the Computational Ecology blog.

7

While the results vary in this case because the column names are numbers, another way I've used is data.frame(rbind(mytable)). Using the example from @X.X:

> freq_t = table(cyl = mtcars$cyl, gear = mtcars$gear)
> freq_t gear
cyl 3 4 5 4 1 8 2 6 2 4 1 8 12 0 2
> data.frame(rbind(freq_t)) X3 X4 X5
4 1 8 2
6 2 4 1
8 12 0 2

If the column names do not start with numbers, the X won't get added to the front of them.

1

Short answer: using as.data.frame.matrix(mytable), as @Victor Van Hee suggested.

Long answer: as.data.frame(mytable) may not work on contingency tables generated by table() function, even if is.matrix(your_table) returns TRUE. It will still melt you table into the factor1 factor2 factori counts format.

Example:

> freq_t = table(cyl = mtcars$cyl, gear = mtcars$gear)
> freq_t gear
cyl 3 4 5 4 1 8 2 6 2 4 1 8 12 0 2
> is.matrix(freq_t)
[1] TRUE
> as.data.frame(freq_t) cyl gear Freq
1 4 3 1
2 6 3 2
3 8 3 12
4 4 4 8
5 6 4 4
6 8 4 0
7 4 5 2
8 6 5 1
9 8 5 2
> as.data.frame.matrix(freq_t) 3 4 5
4 1 8 2
6 2 4 1
8 12 0 2

If you are using the tidyverse, you can use

as_data_frame(table(myvector))

to get a tibble (i.e. a data frame with some minor variations from the base class)

1

This is deprecated:

as.data.frame(my_table)

Instead use this package:

library("quanteda")
convert(my_table, to="data.frame") 
3