2016-06-27 8 views
1

Ich versuche, eine Tabelle mit der Anzahl der Artikel nach Produktname, Jahr und Region verkauft zu erstellen. Ich möchte einen Tisch, der wie folgt aussieht. Gibt es eine Möglichkeit, dies in R zu tun, anstatt eine SQL-Abfrage mit Sqldf-Funktion zu schreiben?Konvertieren Sie n Möglichkeit Kontingenztabelle zu einem Datenrahmen in R

Product_Name  Region  Year  Count 
English Muffins  1  2015  10000 
Bagel     1  2015  5601 
Croissants    .................... 

Hier ist der Code zum Generieren von Beispieldaten. Diese Dummy-Daten entsprechen nicht den obigen Abtastwerten.

Product_Name <- c("English Muffins","croissants","Kaiser rolls","Bagels","cinnamon puff","strawberry pastry") 
Region_ID <- c(1:6) 
Transaction_year <- c(2011:2016) 

x <- data.frame() 
for(i in 1:6) 
    { 
    for (j in 1:6) 
    { 
    for(k in 1:6) 
     { 
     x <- rbind(x, data.frame(Product = Product_Name[i], Region = Region_ID[j], Year = Transaction_year[k])) 
     } 
    } 
    } 

Antwort

3

Die Basisfunktion as.data.frame.table wird dies tun. Ich nehme an, Sie haben entweder oder kann entlang diesen Linien einen R Kontingenztafel machen:

mt <- with(x, table(Product,Region,Year)) 

Sie dann mit dem gewünschten „Langformat“ Objekt erhalten:

str(as.data.frame(mt)) 

'data.frame': 216 obs. of 4 variables: 
$ Product: Factor w/ 6 levels "English Muffins",..: 1 2 3 4 5 6 1 2 3 4 ... 
$ Region : Factor w/ 6 levels "1","2","3","4",..: 1 1 1 1 1 1 2 2 2 2 ... 
$ Year : Factor w/ 6 levels "2011","2012",..: 1 1 1 1 1 1 1 1 1 1 ... 
$ Freq : int 1 1 1 1 1 1 1 1 1 1 ... 

Die anderen nützlichen Tisch Abflachung Funktion ist ftable. Für eine Drei-Wege-Tabelle stellt es eine kompaktere Version der Anzeige, dass print.table ergäbe:

ftable(mt) 
         Year 2011 2012 2013 2014 2015 2016 
Product   Region         
English Muffins 1    1 1 1 1 1 1 
        2    1 1 1 1 1 1 
        3    1 1 1 1 1 1 
        4    1 1 1 1 1 1 
        5    1 1 1 1 1 1 
        6    1 1 1 1 1 1 
croissants  1    1 1 1 1 1 1 
        2    1 1 1 1 1 1 
        3    1 1 1 1 1 1 
        4    1 1 1 1 1 1 
        5    1 1 1 1 1 1 
        6    1 1 1 1 1 1 
Kaiser rolls  1    1 1 1 1 1 1 
        2    1 1 1 1 1 1 
        3    1 1 1 1 1 1 
#-----snipped output-------- 

Auf der anderen Seite, wenn die Anforderung zu replizieren Anzahl von Zeilen durch die Zählvariable ist, dann wäre es thusly erfolgen:

#Makes something like your original dataframe: 
orig <- structure(list(Product_Name = structure(c(2L, 1L), .Label = c("Bagel", 
"English_Muffins"), class = "factor"), Region = c(1L, 1L), Year = c(2015L, 
2015L), Count = c(5L, 4L)), .Names = c("Product_Name", "Region", 
"Year", "Count"), class = "data.frame", row.names = c(NA, -2L)) 

xlong <- orig[ rep(rownames(orig), orig$Count) , ] 
    > xlong 
     Product_Name Region Year Count 
1 English_Muffins  1 2015  5 
1.1 English_Muffins  1 2015  5 
1.2 English_Muffins  1 2015  5 
1.3 English_Muffins  1 2015  5 
1.4 English_Muffins  1 2015  5 
2    Bagel  1 2015  4 
2.1   Bagel  1 2015  4 
2.2   Bagel  1 2015  4 
2.3   Bagel  1 2015  4 
+1

Vielen Dank! Die ftable-Funktion ist, was ich gesucht habe. – user3897

3
Product_Name <- c("English Muffins","croissants","Kaiser rolls","Bagels","cinnamon puff","strawberry pastry") 
Region_ID <- c(1:6) 
Transaction_year <- c(2011:2016) 

x <- data.frame() 
for(i in 1:6) 
{ 
    for (j in 1:6) 
    { 
    for(k in 1:6) 
    { 
     x <- rbind(x, data.frame(Product = Product_Name[i], Region = Region_ID[j], Year = Transaction_year[k])) 
    } 
    } 
} 

x$count <- 1 

xx <- aggregate(x[,"count"],by=list(x$Product,x$Year,x$Region),sum) 
colnames(xx) <- c("Product", "Year", "Region", "Count") 
head(xx) 

      Product Year Region Count 
1 English Muffins 2011  1  1 
2  croissants 2011  1  1 
3  Kaiser rolls 2011  1  1 
4   Bagels 2011  1  1 
5  cinnamon puff 2011  1  1 
6 strawberry pastry 2011  1  1 
3

Ja, Sie können dies tun, indem data.table und eine by Anweisung. Sehr ähnlich ein SQL Gruppe-by:

library(data.table) 
setDT(x)[,count := .N, by = c("Product","Region","Year") ] 
head(x) 

      Product Region Year count 
1: English Muffins  1 2011  1 
2: English Muffins  1 2012  1 
3: English Muffins  1 2013  1 
4: English Muffins  1 2014  1 
5: English Muffins  1 2015  1 
6: English Muffins  1 2016  1 
+1

Vielen Dank! Das war nützlich. Ich frage mich, wie wir dies tun könnten, ohne die "count" -Variable zum ursprünglichen Datensatz hinzuzufügen. – user3897

+1

@ user3897 Dies deutet darauf hin, dass wir alle Antwort-Ersteller Ihre Frage missverstanden haben. Versuchen Sie, den ursprünglichen Datenrahmen zu verwenden und die Anzahl der Zeilen so zu erweitern, dass jede Kombination von Faktoren die Anzahl der Zeilen zählt (ich bin mir ziemlich sicher, dass dies bereits zuvor gefragt und beantwortet wurde.) –

+1

@ 42- Ihre Lösung war Da. as.data.frame (table (x)) gibt 6 * 6 * 6 = 216 Zeilen zurück, was nicht sehr intuitiv ist. – user3897

3

Es gibt keine Notwendigkeit für komplizierten Code hier. Sie benötigen nur eine Zeile Code:

> as.data.frame(table(x)) 
       Product Region Year Freq 
1  English Muffins  1 2011 1 
2   croissants  1 2011 1 
3  Kaiser rolls  1 2011 1 
4    Bagels  1 2011 1 
5  cinnamon puff  1 2011 1 
6 strawberry pastry  1 2011 1 
... 

table Die Funktion der Kontingenztabelle als 3-dimensionales Array erzeugt, und as.data.frame wandelt in einen Datenrahmen in dem Format, das die gewünschten Kontingenztabelle. Wenn x andere Spalten enthält, stellen Sie sicher, dass nur die zu tabellierenden Spalten verwendet werden.

Verwandte Themen