2016-10-29 1 views
0

J'ai un cadre de données avec trois colonnes qui capture les données transactionnelles, y compris CustomerName, OrderDate et le nom du ou des produits qui ont été achetés. Je dois transformer la base de données en une autre base de données avec un format tel que tous les articles achetés par un client à une date unique sont dans une rangée. Comme il s'agit d'un grand ensemble de données, existe-t-il un moyen efficace de réaliser cette transformation, sans utiliser de boucles?R Transformation de données

De plus, le nombre de colonnes pour les produits dans la trame de données doit être égal au nombre maximal de produits achetés par un client au cours d'une même journée. S'il vous plaît trouver un exemple de trame de données avant et après la transformation

Original Data:

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 

post-tranformation:

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 

De plus, le nombre de colonnes pour les produits dans le cadre de données doit être égal au nombre maximum de produits achetés par un client au cours d'une même journée.

+0

puisque vous avez des doublons dans la date, ajoutez une nouvelle variable pour l'heure, et il s'agit d'un remodelage de base long-à-large: 'data $ time <-ave (données $ Client, données $ Client, FUN = seq_along); reshape (données, dir = 'wide', idvar = c ('Customer', 'OrderDate')) ' – rawr

+0

Merci, rawr, pour la solution rapide! votre solution résout la plupart du problème. cependant, pour John le 2 octobre, il y a une NA dans Product1, des oeufs dans le produit 2 et du pain dans le product3. Je voudrais avoir des oeufs dans le produit1 et du pain dans le produit 2. est-il un moyen de réparer cela en utilisant remodeler ou autrement? – xineers

+0

J'aurais dû regrouper par client et date 'data $ time <- avec (data, ave (client, liste (Customer, OrderDate), FUN = seq_along))' – rawr

Répondre

0

Puisque vous avez parlé de grand ensemble de données (alors l'efficacité est une question très importante à Toke en considération), voici une solution dplyr et 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

merci les deux pour les solutions soignées. La solution dplyr/reshape2 est rapide sur le grand ensemble de données! – xineers