2015-05-27 10 views
5

Ich bin mir bewusst, dass a little programming Konvertieren von Tabellen mit festen Dimensionen ermöglicht, wie z. von table(), zurück in Beobachtungsdaten. So ist das Ziel, eine Frequenztabelle wie diese zu konvertieren ...Gibt es eine allgemeine Umkehrung der Funktion table()?

(flower.freqs <- with(iris,table(Petal=cut(Petal.Width,2),Species))) 
      Species 
Petal   setosa versicolor virginica 
    (0.0976,1.3]  50   28   0 
    (1.3,2.5]   0   22  50 

... zurück in ein data.frame() mit einer Zeilennummer, die die Summe der Anzahl der Eingangsmatrix entspricht, während die Zelle Werte sind der Eingabedimensionen erhalten:

 Petal Species 
1 (0.0976,1.3] setosa 
2 (0.0976,1.3] setosa 
3 (0.0976,1.3] setosa 
# ... (150 rows) ... 

Mit etwas Herumprobieren I einen groben Prototypenbau, die auch höherdimensionalen Eingänge verdauen sollte:

tableinv <- untable <- function(x) { 
    stopifnot(is.table(x)) 
    obs <- as.data.frame(x)[rep(1:prod(dim(x)),c(x)),-length(dim(x))-1] 
    rownames(obs) <- NULL; obs 
} 

> head(tableinv(flower.freqs)); dim(tableinv(flower.freqs)) 
    Petal Species 
1 (0.0976,1.3] setosa 
2 (0.0976,1.3] setosa 
3 (0.0976,1.3] setosa 
4 (0.0976,1.3] setosa 
5 (0.0976,1.3] setosa 
6 (0.0976,1.3] setosa 
[1] 150 2 
> head(tableinv(Titanic)); nrow(tableinv(Titanic))==sum(Titanic) 
    Class Sex Age Survived 
1 3rd Male Child  No 
2 3rd Male Child  No 
3 3rd Male Child  No 
4 3rd Male Child  No 
5 3rd Male Child  No 
6 3rd Male Child  No 
[1] TRUE 

ich bin obvio Natürlich stolz, dass diese Bricolage Multi-Attribut data.frame() s aus höherdimensionalen Häufigkeitstabellen wie Titanic rekonstruiert - aber gibt es eine etablierte (eingebaute, kampferprobte) allgemeine Umkehrung zu Tabelle(), idealerweise eine, die nicht von a abhängt spezifische Bibliothek, die weiß, wie man mit unbeschrifteten Dimensionen umgeht, die so optimiert ist, dass sie bei umfangreichen Eingaben nicht erstickt, und die vernünftig mit Tabelleneingaben umgeht, die sowohl Faktoren- als auch Nicht-Faktor-Beobachtungseingaben entsprechen?

+3

Ich weiß nicht, ob es eine Inverse von 'table' gibt, aber ich denke, Sie könnten Ihren Code ein wenig verbessern. Zum Beispiel würde ich einfach versuchen: 'lev <-expand.grid (dimnames (mytable)); lev [rep (1: nwer (lev), as.vector (meinetable)),]' – nicola

+0

@Nicola: Du bist richtig, danke. Und ein weiterer vorübergehender Kommentar (dass jemand kurz wieder eingezogen hatte) deutete auch an, dass 'as.data.frame.table()' uns auf halbem Wege dahin bringen würde ... – texb

+1

Nicht unbedingt besser, aber sobald du 'as.data.frame' verwendest , Sie können: 'DF [rep (rownames (DF), DF $ Freq), -ncol (DF)]' was oberflächlich erscheint ein wenig einfacher. – BrodieG

Antwort

0

Ich glaube, dass Ihre Lösung ziemlich gut ist. Auf jedem Fall ganz ähnlich wie ich diese Frage beantworten würde, ist:

tableinv <- function(x){ 
     y <- x[rep(rownames(x),x$Freq),1:(ncol(x)-1)] 
     rownames(y) <- c(1:nrow(y)) 
     return(y)} 
survivors <- as.data.frame(Titanic) 
surv.invtab <- tableinv(survivors) 

die

> head(surv.invtab) 
    Class Sex Age Survived 
1 3rd Male Child  No 
2 3rd Male Child  No 
3 3rd Male Child  No 
4 3rd Male Child  No 
5 3rd Male Child  No 
6 3rd Male Child  No 

In Bezug auf das Beispiel mit den Blumen liefert, mit der Funktion tableinv() wie oben definiert ist, wäre es zunächst sein notwendig, die Daten in einen Datenrahmen zu konvertieren:

flower.freqs <- with(iris,table(Petal=cut(Petal.Width,2),Species)) 
flower.freqs <- as.data.frame(flower.freqs) 
flower.invtab <- tableinv(flower.freqs) 

Das Ergebnis in diesem Fall ist

> head(flower.invtab) 
     Petal Species 
1 (0.0976,1.3] setosa 
2 (0.0976,1.3] setosa 
3 (0.0976,1.3] setosa 
4 (0.0976,1.3] setosa 
5 (0.0976,1.3] setosa 
6 (0.0976,1.3] setosa 

Hoffe das hilft.

Verwandte Themen