Cómo convertir una tabla en un marco de datos

167

Tengo una tabla en R que tiene str()de esto:

 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"

Y se ve así cuando lo imprimo:

                    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

Quiero deshacerse de la xe yy la convierten en una trama de datos que se ve exactamente igual que el anterior (tres filas, cuatro columnas), pero sin la xo y. Si uso as.data.frame(mytable), en cambio obtengo esto:

                    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

Probablemente no entiendo fundamentalmente cómo se relacionan las tablas con los marcos de datos.

Victor Van Hee
fuente
2
Al buscar, me sorprendió lo difícil que era encontrar una pregunta similar sobre SO. Aquí hay uno: stackoverflow.com/questions/5855225/... Es una maniobra bastante básica y se describe en ?xtabs(no es necesariamente la ubicación más obvia).
IRTFM
Bastante seguro de que todo lo que necesita hacer es establecer deparse.level = 0(o posiblemente 2) en la llamada atable
Rich Scriven

Respuestas:

322

Ya lo descubrí:

as.data.frame.matrix(mytable) 

hace lo que necesito: aparentemente, la tabla debe convertirse de alguna manera en una matriz para traducirla adecuadamente en un marco de datos. Encontré más detalles sobre esta función as.data.frame.matrix () para tablas de contingencia en el blog Computational Ecology .

Victor Van Hee
fuente
31
O simplemente as.data.frame(mytable). ( is.matrix(mytable)revelará que las tablas realmente son solo matrices disfrazadas, y as.data.frame.matrixes el método que se despacha cuando as.data.frame()se pasa un argumento de matriz.)
Josh O'Brien
16
Josh: en el ejemplo que se muestra en la parte superior, como.data.frame (mytable) no funcionó, por eso Victor me hizo la pregunta, pensé. ¿Podrías aclarar?
Heather Stark
44
@HeatherStark Sospecho que esto se debe a as.data.frame.tableque se está enviando, en lugar de ser menos específico as.data.frame.matrix.
jbaums
3
Muy buen hallazgo. lo único que no me gusta es que mis factores xtab (primera "columna") se convierten en row.names. He logrado agregar una columna usando los row.namesvalores, pero prefiero evitar as.data.frame.matrixescribir row.namesen primer lugar ...
Thieme Hennis
as.data.frame.matrix(table(x))me da Error in seq_len(ncols) : argument must be coercible to non-negative integer, mientras as.data.frame(table(x))trabaja, donde xsolo hay un vector numéricoc(1,2,...)
PatrickT
16

Si bien los resultados varían en este caso porque los nombres de las columnas son números, otra forma que he usado es data.frame(rbind(mytable)). Usando el ejemplo de @XX:

> 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

Si los nombres de las columnas no comienzan con números, Xno se agregarán al frente de ellos.

BLT
fuente
En realidad, esto también funciona mejor que as.data.frame.matrix en mi ejemplo que devuelve un error: out <- structure (c (zone1 = 1208160L, zone2 = 1126841L, zone3 = 2261808L, zone4 = 1827557L, zone5 = 1038999L, zone6 = 353569L, zone7 = 351484L, zone8 = 441930L, zone9 = 25266L, zoneNA = 14751L), .Dim = 10L, .Dimnames = list (c ("zone1", "zone2", "zone3", "zone4", "zone5 "," zone6 "," zone7 "," zone8 "," zone9 "," zoneNA ")), class =" table ")> as.data.frame.matrix (out) Error en d [[2L]]: subíndice fuera de límites
cmbarbu
11

Respuesta corta: usando as.data.frame.matrix(mytable), como sugirió @Victor Van Hee.

Respuesta larga: as.data.frame(mytable)puede que no funcione en tablas de contingencia generadas por table()función, incluso si se is.matrix(your_table)devuelve TRUE. Seguirá derritiendo su tabla en el factor1 factor2 factori countsformato.

Ejemplo:

> 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
XX
fuente
7

Si está usando el tidyverse , puede usar

as_data_frame(table(myvector))

para obtener un tibble (es decir, un marco de datos con algunas variaciones menores de la clase base)

Ben
fuente
depende de lo que quiera trabajar con marcos de datos o tibbles
Dimitrios Zacharatos
-1

Esto es depricate

as.data.frame (mytable)

En su lugar use esto

biblioteca ("quanteda")

convertir (mytable, to = "data.frame")

Odeyinka Olubunmi
fuente
1
convertno es parte de la distribución normal de R. Tengo could not find function "convert"¿Qué biblioteca necesitas para esto?
Mark Lakata
biblioteca ("quanteda")
Odeyinka Olubunmi