2013-01-24 15 views
6

Obecnie uczę się pracować z data.frame i jestem bardzo zdezorientowany, jak zmienić ich kolejność.Przeformułowywanie magii na data.frame

W tej chwili mam data.frame że pokaże:

  • Kolumna 1: nazwę sklepu
  • kolumna 2: produkt
  • kolumna 3: ilość zakupu tego produktu o tym sklepie

lub wizualnie coś takiego:

+---+-----------+-------+----------+--+ 
| | Shop.Name | Items | Product | | 
+---+-----------+-------+----------+--+ 
| 1 | Shop1  |  2 | Product1 | | 
| 2 | Shop1  |  4 | Product2 | | 
| 3 | Shop2  |  3 | Product1 | | 
| 4 | Shop3  |  2 | Product1 | | 
| 5 | Shop3  |  1 | Product4 | | 
+---+-----------+-------+----------+--+ 

Co chciałbym osiągnąć jest następujące "shop-centric" struktura:

  • kolumna 1: nazwa sklepu
  • kolumna 2: Produkty sprzedawane na Produkt1
  • kolumna 3: Produkty sprzedawane na Produkt2
  • kolumna 4: Produkty sprzedawane na product3 ...

Kiedy nie ma linii do konkretnego sklepu/produktu (z powodu braku sprzedaży), chciałbym stworzyć 0.

lub

+---+-------+-------+-------+-------+-------+-----+--+--+ 
| | Shop | Prod1 | Prod2 | Prod3 | Prod4 | ... | | | 
+---+-------+-------+-------+-------+-------+-----+--+--+ 
| 1 | Shop1 |  2 |  4 |  0 |  0 | ... | | | 
| 2 | Shop2 |  3 |  0 |  0 |  0 | ... | | | 
| 3 | Shop3 |  2 |  0 |  0 |  1 | ... | | | 
+---+-------+-------+-------+-------+-------+-----+--+--+ 
+3

Mieć spójrz na funkcję 'reshape' lub' dcast' w pakiecie ** reshape2 **. – joran

+0

http://stackoverflow.com/a/9617424/210673 ma długą listę sposobów, aby to zrobić. – Aaron

Odpowiedz

12

odpowiedzi tak daleko działa do pewnego stopnia, ale nie w pełni odpowiada na twoje pytanie. W szczególności nie poruszają kwestii sprawy, w której nie ma sklepów, które sprzedałyby dany produkt. Na podstawie przykładowego wejścia i pożądanego wyniku nie było sklepów, które sprzedałyby "Produkt3". Rzeczywiście, "Product3" nawet nie pojawia się w twoim źródle data.frame. Ponadto nie odnoszą się do możliwej sytuacji posiadania więcej niż jednego wiersza dla każdej kombinacji Shop + Produkt.

Oto zmodyfikowana wersja danych i oba rozwiązania do tej pory. Dodałem kolejny wiersz dla kombinacji "Sklep1" i "Produkt1". Zwróć uwagę, że przekonwertowałem Twoje produkty na zmienną factor, która obejmuje poziomy, które może przyjmować zmienna, nawet jeśli żaden z przypadków nie ma tego poziomu.

mydf <- data.frame(
    Shop.Name = c("Shop1", "Shop1", "Shop2", "Shop3", "Shop3", "Shop1"), 
    Items = c(2, 4, 3, 2, 1, 2), 
    Product = factor(
    c("Product1", "Product2", "Product1", "Product1", "Product4", "Product1"), 
    levels = c("Product1", "Product2", "Product3", "Product4"))) 
  1. dcast z "reshape2"

    library(reshape2) 
    dcast(mydf, formula = Shop.Name ~ Product, value="Items", fill=0) 
    # Using Product as value column: use value.var to override. 
    # Aggregation function missing: defaulting to length 
    # Error in .fun(.value[i], ...) : 
    # 2 arguments passed to 'length' which requires 1 
    

    Wha? Nagle nie działa. Zrób to zamiast tego:

    dcast(mydf, formula = Shop.Name ~ Product, 
         fill = 0, value.var = "Items", 
         fun.aggregate = sum, drop = FALSE) 
    # Shop.Name Product1 Product2 Product3 Product4 
    # 1  Shop1  4  4  0  0 
    # 2  Shop2  3  0  0  0 
    # 3  Shop3  2  0  0  1 
    
  2. Let's be oldschool.cast z "przekształcenia"

    library(reshape) 
    cast(mydf, formula = Shop.Name ~ Product, value="Items", fill=0) 
    # Aggregation requires fun.aggregate: length used as default 
    # Shop.Name Product1 Product2 Product4 
    # 1  Shop1  2  1  0 
    # 2  Shop2  1  0  0 
    # 3  Shop3  1  0  1 
    

    Eh. Spróbuj ponownie: zamiast tego spróbuj:

    cast(mydf, formula = Shop.Name ~ Product, 
        value = "Items", fill = 0, 
        add.missing = TRUE, fun.aggregate = sum) 
    # Shop.Name Product1 Product2 Product3 Product4 
    # 1  Shop1  4  4  0  0 
    # 2  Shop2  3  0  0  0 
    # 3  Shop3  2  0  0  1 
    
  3. Wróćmy do podstaw. xtabs z bazy badawczo

    xtabs(Items ~ Shop.Name + Product, mydf) 
    #   Product 
    # Shop.Name Product1 Product2 Product3 Product4 
    #  Shop1  4  4  0  0 
    #  Shop2  3  0  0  0 
    #  Shop3  2  0  0  1 
    

    Lub, jeśli wolisz data.frame (zauważmy, że zmienna "Shop.Name" został przekształcony w row.names na data.frame):

    as.data.frame.matrix(xtabs(Items ~ Shop.Name + Product, mydf)) 
    #  Product1 Product2 Product3 Product4 
    # Shop1  4  4  0  0 
    # Shop2  3  0  0  0 
    # Shop3  2  0  0  1 
    
+1

To jest bardziej kompleksowe niż inne rozwiązania opublikowane w http://stackoverflow.com/questions/9617348/reshape-three-column-data-frame-to-matrix –

+0

@Anando Mahto, mam do czynienia z tym samym problemem Jeśli masz czas, aby odpowiedzieć na moje pytanie, będę świetny. w moim zestawie danych nazwa sklepu to identyfikator użytkownika, który jest unikatowy i na przykład chcę widzieć jako pierwszy wiersz, jeśli id_użytkownika = 5, czy mogę to zrobić? Z góry bardzo dziękuję –

1

Zastosowanie dcast z reshape2 Biblioteka:

library(reshape2) 

> df <- data.frame(Shop.Name=rep(c("Shop1","Shop2","Shop3"),each=3), 
+     Items=rpois(9,5), 
+     Product=c(rep(c("Prod1","Prod2","Prod3","Prod4"),2),"Prod5") 
+) 
> df 
    Shop.Name Items Product 
1  Shop1  6 Prod1 
2  Shop1  5 Prod2 
3  Shop1  6 Prod3 
4  Shop2  5 Prod4 
5  Shop2  6 Prod1 
6  Shop2  6 Prod2 
7  Shop3  4 Prod3 
8  Shop3  7 Prod4 
9  Shop3  5 Prod5 
> dcast(df,Shop.Name ~ Product,value.var="Items",fill=0) 
    Shop.Name Prod1 Prod2 Prod3 Prod4 Prod5 
1  Shop1  6  5  6  0  0 
2  Shop2  6  6  0  5  0 
3  Shop3  0  0  4  7  5 
+0

Niezupełnie. Zobacz [moja odpowiedź] (http://stackoverflow.com/a/14515736/1270695). – A5C1D2H2I1M1N2O1R2T1

0

Jeśli chcesz użyć oryginalnego opakowania przekształcenia dowolnego powodu:

Shop.Name <- c("Shop1", "Shop1", "Shop2", "Shop3", "Shop3") 
Items <- c(2,4,3,2,1) 
Product <- c("Product1", "Product2", "Product1", "Product1", "Product4") 
(df <- data.frame(Shop.Name, Items, Product)) 

cast(df, formula = Shop.Name ~ Product, value="Items", fill=0)