So konvertieren Sie eine Tabelle in einen Datenrahmen

166

Ich habe eine Tabelle in R, die davon hat str():

 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"

Und sieht beim Drucken so aus:

                    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

Ich möchte das xund loswerden yund es in einen Datenrahmen konvertieren, der genauso aussieht wie oben (drei Zeilen, vier Spalten), aber ohne das xoder y. Wenn ich benutze as.data.frame(mytable), bekomme ich stattdessen folgendes:

                    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

Ich verstehe wahrscheinlich grundsätzlich nicht, wie sich Tabellen auf Datenrahmen beziehen.

Victor Van Hee
quelle
2
Bei der Suche war ich überrascht, wie schwierig es war, eine ähnliche Frage zu SO zu finden. Hier ist eines: stackoverflow.com/questions/5855225/… Es ist ein ziemlich einfaches Manöver und beschrieben in ?xtabs(nicht das ist unbedingt der offensichtlichste Ort.)
IRTFM
Ziemlich sicher, dass alles, was Sie tun müssen, ist deparse.level = 0(oder möglicherweise 2) in dem Anruf antable
Rich Scriven

Antworten:

321

Ich habe es schon herausgefunden:

as.data.frame.matrix(mytable) 

macht was ich brauche - anscheinend muss die Tabelle irgendwie in eine Matrix konvertiert werden, um angemessen in einen Datenrahmen übersetzt zu werden. Weitere Details zu dieser Funktion as.data.frame.matrix () für Kontingenztabellen habe ich im Blog Computational Ecology gefunden .

Victor Van Hee
quelle
31
Oder einfach nur as.data.frame(mytable). ( is.matrix(mytable)wird zeigen, dass Tabellen wirklich nur verkleidete Matrizen sind, und as.data.frame.matrixist die Methode, die as.data.frame()
Josh O'Brien
16
Josh - in dem oben gezeigten Beispiel hat as.data.frame (mytable) nicht funktioniert - deshalb hat Victor die Frage gestellt, dachte ich? Könnten Sie das klarstellen?
Heather Stark
4
@HeatherStark Ich vermute, das liegt daran, as.data.frame.tabledass es tatsächlich versendet wird und nicht an dem weniger spezifischen as.data.frame.matrix.
Jbaums
3
sehr schöner Fund. Das einzige, was ich nicht mag, ist, dass meine xtab-Faktoren (erste "Spalte") zu werden row.names. Ich habe es geschafft, eine Spalte mit den row.namesWerten hinzuzufügen , aber ich vermeide eher das as.data.frame.matrixSchreiben row.namesan erster Stelle.
Thieme Hennis
as.data.frame.matrix(table(x))gibt mir Error in seq_len(ncols) : argument must be coercible to non-negative integerwährend der as.data.frame(table(x))Arbeit, wo xnur ein numerischer Vektor istc(1,2,...)
PatrickT
16

Während die Ergebnisse in diesem Fall variieren, weil die Spaltennamen Zahlen sind, habe ich sie auch verwendet data.frame(rbind(mytable)). Verwenden Sie das Beispiel von @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

Wenn die Spaltennamen nicht mit Zahlen beginnen, Xwerden diese nicht an der Vorderseite hinzugefügt.

BLT
quelle
Dies funktioniert in meinem Beispiel auch besser als as.data.frame.matrix, das einen Fehler zurückgibt: out <- Struktur (c (Zone1 = 1208160L, Zone2 = 1126841L, Zone3 = 2261808L, Zone4 = 1827557L, Zone5 = 1038999L, Zone6) = 353569L, Zone7 = 351484L, Zone8 = 441930L, Zone9 = 25266L, ZoneNA = 14751L), .Dim = 10L, .Dimnames = Liste (c ("Zone1", "Zone2", "Zone3", "Zone4", "Zone5" "," zone6 "," zone7 "," zone8 "," zone9 "," zoneNA ")), class =" table ")> as.data.frame.matrix (out) Fehler in d [[2L]]: Index außerhalb der Grenzen
cmbarbu
11

Kurze Antwort: Verwenden as.data.frame.matrix(mytable), wie von @Victor Van Hee vorgeschlagen.

Lange Antwort: Funktioniert as.data.frame(mytable)möglicherweise nicht mit von der table()Funktion generierten Kontingenztabellen , selbst wenn sie is.matrix(your_table)zurückgegeben werden TRUE. Es wird immer noch Ihre Tabelle in das factor1 factor2 factori countsFormat schmelzen .

Beispiel:

> 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
quelle
7

Wenn Sie die Tidyverse verwenden , können Sie verwenden

as_data_frame(table(myvector))

um ein Tibble zu erhalten (dh einen Datenrahmen mit einigen geringfügigen Abweichungen von der Basisklasse)

Ben
quelle
hängt davon ab, was Sie mit Datenrahmen oder Tibbles arbeiten möchten
Dimitrios Zacharatos
-1

Das ist beraubt

as.data.frame (mytable)

Verwenden Sie stattdessen dies

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

Odeyinka Olubunmi
quelle
1
convertist nicht Teil der normalen R-Verteilung. Ich habe could not find function "convert"Welche Bibliothek brauchst du dafür?
Mark Lakata