2016-06-27 1 views
1

Я пытаюсь создать таблицу с количеством предметов, продаваемых по названию продукта, году и региону. Я хочу таблицу, которая выглядит ниже. Есть ли способ сделать это в R, а не писать sql-запрос с использованием функции sqldf?Преобразование n-мерной таблицы непредвиденных ситуаций в dataframe в R

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

Вот код для создания данных образца. Эти фиктивные данные не соответствуют приведенным выше отсчетам.

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])) 
     } 
    } 
    } 

ответ

3

Базовая функция as.data.frame.table сделает это. Я предполагаю, что вы либо иметь или может сделать таблицу R на случай непредвиденных обстоятельств вдоль этих линий:

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

Затем вы получите желаемый «длинный формат» объект с:

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

другой полезной настольной уплощением функция ftable. Для трехсторонний стола он представляет собой более компактную версию дисплея, что print.table бы выхода:

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

С другой стороны, если запрос должны повторить количество строк переменной Count, то это будет сделано таким образом:

#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

Спасибо! Функция ftable - это то, что я искал. – 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

Да, вы можете сделать это с помощью data.table и by заявление. Очень похоже на SQL групповых по:

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

Спасибо! Это было полезно. Мне интересно, как мы могли это сделать, не добавляя переменную «count» в исходный набор данных. – user3897

+1

@ user3897 Это говорит о том, что все мы, ответчики, неправильно поняли ваш вопрос. Вы пытаетесь взять исходный блок данных и расширить количество строк, чтобы каждая комбинация факторов имела «Counts» количество строк? (Я совершенно уверен, что это было задано и ответили ранее.) –

+1

@ 42- Ваше решение было так как as.data.frame (table (x)) возвращает 6 * 6 * 6 = 216 строк, которые не очень интуитивны. – user3897

3

Там нет необходимости сложного кода здесь. Все, что вам нужно, это одна строка кода:

> 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 функция производит таблицы сопряженности в 3-мерном массиве, и as.data.frame преобразует таблицы сопряженности в кадр данных в формате, который вы хотите. Если x содержит другие столбцы, обязательно подмножите его только для столбцов, которые вы хотите скопировать.

Смежные вопросы