Comment convertir une table en bloc de données

167

J'ai une table dans R qui a str()de ceci:

 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"

Et ça ressemble à ça quand je l'imprime:

                    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

Je veux me débarrasser du xet yet le convertir en un bloc de données qui ressemble exactement à ce qui précède (trois lignes, quatre colonnes), mais sans le xou y. Si j'utilise as.data.frame(mytable), à la place j'obtiens ceci:

                    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

Je ne comprends probablement pas fondamentalement comment les tableaux se rapportent aux cadres de données.

Victor Van Hee
la source
2
Lors de la recherche, j'ai été surpris de voir à quel point il était difficile de trouver une question similaire sur SO. En voici une: stackoverflow.com/questions/5855225/ ... C'est une manœuvre assez basique et décrite dans ?xtabs(ce n'est pas nécessairement l'emplacement le plus évident.)
IRTFM
À peu près sûr, tout ce que vous avez à faire est de définir deparse.level = 0(ou éventuellement 2) dans l'appel àtable
Rich Scriven

Réponses:

322

Je l'ai déjà compris:

as.data.frame.matrix(mytable) 

fait ce dont j'ai besoin - apparemment, la table doit d'une manière ou d'une autre être convertie en matrice pour être correctement traduite en un bloc de données. J'ai trouvé plus de détails sur cette fonction as.data.frame.matrix () pour les tables de contingence sur le blog Computational Ecology .

Victor Van Hee
la source
31
Ou juste as.data.frame(mytable). ( is.matrix(mytable)révélera que les tables ne sont en réalité que des matrices habillées, et as.data.frame.matrixc'est la méthode qui est envoyée quand as.data.frame()un argument de matrice est passé.)
Josh O'Brien
16
Josh - dans l'exemple montré en haut, as.data.frame (mytable) ne fonctionnait pas - c'est pourquoi Victor posait la question, j'ai pensé? Pourriez-vous clarifier?
Heather Stark
4
@HeatherStark Je soupçonne que c'est parce que c'est en fait as.data.frame.tablequi est envoyé, plutôt que le moins spécifique as.data.frame.matrix.
jbaums
3
très belle trouvaille. la seule chose que je n'aime pas, c'est que mes facteurs xtab (première "colonne") se transforment en row.names. J'ai réussi à ajouter une colonne en utilisant les row.namesvaleurs, mais j'évite plutôt d' as.data.frame.matrixécrire row.namesen premier lieu ..
Thieme Hennis
as.data.frame.matrix(table(x))me donne Error in seq_len(ncols) : argument must be coercible to non-negative integer, tout en as.data.frame(table(x))fonctionnant, où xest juste un vecteur numériquec(1,2,...)
PatrickT
16

Bien que les résultats varient dans ce cas parce que les noms de colonnes sont des nombres, une autre manière que j'ai utilisée est data.frame(rbind(mytable)). En utilisant l'exemple 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 les noms de colonnes ne commencent pas par des nombres, Xils ne seront pas ajoutés au début .

BLT
la source
Cela fonctionne également mieux que as.data.frame.matrix dans mon exemple qui renvoie une erreur: 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) Erreur dans d [[2L]]: indice hors limites
cmbarbu
11

Réponse courte: utilisation as.data.frame.matrix(mytable) , comme @Victor Van Hee l'a suggéré.

Réponse longue: as.data.frame(mytable)peut ne pas fonctionner sur les tables de contingence générées par la table()fonction, même si is.matrix(your_table)retourne TRUE. Il fera toujours fondre votre table dans lefactor1 factor2 factori counts format.

Exemple:

> 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
la source
7

Si vous utilisez le tidyverse , vous pouvez utiliser

as_data_frame(table(myvector))

pour obtenir un tibble (c'est-à-dire une trame de données avec quelques variations mineures par rapport à la classe de base)

Ben
la source
dépend de ce que vous voulez travailler avec des dataframes ou des tibbles
Dimitrios Zacharatos
-1

C'est déprécier

as.data.frame (ma table)

Utilisez plutôt ceci

bibliothèque ("quanteda")

convert (ma table, en = "data.frame")

Odeyinka Olubunmi
la source
1
convertne fait pas partie de la distribution R normale. J'ai de could not find function "convert"quelle bibliothèque avez-vous besoin pour cela?
Mark Lakata
library ("quanteda")
Odeyinka Olubunmi