2016-10-29 18 views
0

私はCustomerData、OrderDate、および購入された製品の名前を含むトランザクションデータをキャプチャする3つの列を持つデータフレームを持っています。私は、単一の日付で顧客によって購入されたすべてのアイテムが1つの行にあるような形式でデータフレームを別のデータフレームに変換する必要があります。Rデータ変換

大規模なデータセットを処理しているので、この変換に効率的な方法があります。うまくいけば、forループを使用しないでください。

また、データフレーム内の製品の列数は、任意の顧客が1日に購入できる最大製品数と等しくなければなりません。

オリジナルデータの前と変換後のデータフレームの一例を見つけてください:

data <- data.frame(Customer = c("John", "John", "John", "Tom", "Tom", "Tom", "Sally", "Sally", "Sally", "Sally"), 
        OrderDate = c("1-Oct", "2-Oct", "2-Oct", "2-Oct","2-Oct", "2-Oct", "3-Oct", "3-Oct", "3-Oct", "3-Oct"), 
        Product = c("Milk", "Eggs", "Bread", "Chicken", "Pizza", "Beer", "Salad", "Apples", "Eggs", "Wine"), 
        stringsAsFactors = FALSE) 

# Customer OrderDate Product 
# 1  John  1-Oct Milk 
# 2  John  2-Oct Eggs 
# 3  John  2-Oct Bread 
# 4  Tom  2-Oct Chicken 
# 5  Tom  2-Oct Pizza 
# 6  Tom  2-Oct Beer 
# 7  Sally  3-Oct Salad 
# 8  Sally  3-Oct Apples 
# 9  Sally  3-Oct Eggs 
# 10 Sally  3-Oct Wine 

ポスト形質転換の:さらに

datatransform <- as.data.frame(matrix(NA, nrow = 4, ncol = 6)) 
colnames(datatransform) <- c("Customer", "OrderDate", "Product1", "Product2", "Product3", "Product4") 
datatransform$Customer <- c("John", "John", "Tom", "Sally") 
datatransform$OrderDate <- c("1-Oct", "2-Oct", "2-Oct", "3-Oct") 
datatransform[1, 3:6] <- c("Milk", "", "", "") 
datatransform[2, 3:6 ] <- c("Eggs", "Bread", "", "") 
datatransform[3, 3:6 ] <- c("Chicken", "Pizza", "Beer", "") 
datatransform[4, 3:6 ] <- c("Salad", "Apples", "Eggs", "Wine") 

# Customer OrderDate Product1 Product2 Product3 Product4 
# 1  John  1-Oct  Milk       
# 2  John  2-Oct  Eggs Bread     
# 3  Tom  2-Oct Chicken Pizza  Beer   
# 4 Sally  3-Oct Salad Apples  Eggs  Wine 

、データフレーム内の製品の列数1日に任意の顧客が購入する製品の最大数と等しくなければなりません。あなたが大規模なデータセットについて話しましたので

+0

日付内の重複を持っているので、ために新しい変数を追加しますこれは基本的なロング・トゥ・ワイド・リシェイプです。 'data $ time < - ave(data $ Customer、data $ Customer、FUN = seq_along); reshape(data、dir = 'wide'、idvar = c( 'Customer'、 'OrderDate')) ' – rawr

+0

プロンプトで解決していただきありがとうございます。あなたのソリューションは問題のほとんどを解決します。しかし、oct2のJohnについては、Product1にNA、Product2に卵、Product3にBreadがあります。私は製品1に卵を、製品2にパンを置いておきたいと思います。 – xineers

+0

私は顧客と日付の両方で 'data $ time < - (data、ave(Customer、list)(Customer、OrderDate)、FUN = seq_along))でグループ化する必要があります。 ' – rawr

答えて

0

は(そして効率を考慮に土気するために非常に重要な問題である)、ここではdplyrとreshape2ソリューションです:

library(reshape2) 
library(dplyr) 

data %>% group_by(Customer, OrderDate) %>% 
      mutate(ProductValue = paste0("Product", 1:n())) %>% 
      dcast(Customer + OrderDate ~ ProductValue, value.var = "Product" ) %>% 
      arrange(OrderDate) 

    Customer OrderDate Product1 Product2 Product3 Product4 
1  John  1-Oct  Milk  <NA>  <NA>  <NA> 
2  John  2-Oct  Eggs Bread  <NA>  <NA> 
3  Tom  2-Oct Chicken Pizza  Beer  <NA> 
4 Sally  3-Oct Salad Apples  Eggs  Wine 
+0

dplyr/reshape2ソリューションは、大規模なデータセットで高速です! – xineers

関連する問題