2016-04-21 3 views
2

Я есть корзина покупок, данные, которые выглядят как образец dataframe ниже:Соберите несколько столбцов с tidyr

sample_df<-data.frame(
    clientid=1:10, 
    ProductA=c("chair","table","plate","plate","table","chair","table","plate","chair","chair"), 
    QuantityA=c(1,2,1,1,1,1,2,3,1,2), 
    ProductB=c("table","doll","shoes","","door","","computer","computer","","plate"), 
    QuantityB=c(3,1,2,"",2,"",1,1,"",1) 
) 
#sample data frame 
    clientid ProductA QuantityA ProductB QuantityB 
1 1  chair 1   table 3 
2 2  table 2   doll 1 
3 3  plate 1   shoes 2    
4 4  plate 1    
... 
10 10  chair 2   plate 1 

Я хотел бы превратить его в другой формат, который будет как:

#ideal data frame 
    clientid ProductNumber Product Quantity 
1 1  A    chair 1 
2 1  B    table 3 
3 2  A    table 2 
4 2  B    doll 1 
... 
11 6  A    chair 1 
... 
17 10  A    chair 2 
18 10  B    plate 1 

Я попытался

library(tidyr) 
sample_df_gather<- sample_df %>% select(clientid, ProductA, ProductB) 
%>% gather(ProductNumber, value, -clientid) %>% filter(!is.na(value)) 

#this gives me 
    clientid ProductNumber value 
1 1  ProductA  chair 
2 2  ProductB  table 
3 3  ProductA  plate 
4 4  ProductB  plate 
... 

Однако, я не знаю, как добавить Количество в кадре данных. Кроме того, в фактическом фрейме данных есть больше столбцов, таких как Title, price, которые я хотел бы преобразовать в идеальный кадр данных. Есть ли способ преобразовать данные в идеальный формат?

+0

Для величину В, вы действительно не хотите использовать "" ... попробуйте NA вместо этого. – Frank

+1

'reshape (sample_df, dir = 'long', variableing = list (c (2,4), c (3,5)))' дает мне 20 строк или это неправильно – rawr

+1

спасибо @Frank! представленная здесь функция перестройки решает мою проблему. @aosmith, да, я проверил его, прежде чем задавать этот вопрос, но до сих пор не смог найти способ превратить его в идеальный кадр данных. –

ответ

6

С data.table:

library(data.table) 
res = melt(setDT(sample_df), 
    measure.vars = patterns("^Product", "^Quantity"), 
    variable.name = "ProductNumber") 
res[, ProductNumber := factor(ProductNumber, labels = c("A","B"))] 

который дает

clientid ProductNumber value1 value2 
1:  1    A chair  1 
2:  2    A table  2 
3:  3    A plate  1 
4:  4    A plate  1 
5:  5    A table  1 
6:  6    A chair  1 
7:  7    A table  2 
8:  8    A plate  3 
9:  9    A chair  1 
10:  10    A chair  2 
11:  1    B table  3 
12:  2    B  doll  1 
13:  3    B shoes  2 
14:  4    B  NA  NA 
15:  5    B  door  2 
16:  6    B  NA  NA 
17:  7    B computer  1 
18:  8    B computer  1 
19:  9    B  NA  NA 
20:  10    B plate  1 

данных (так как исходные данные в OP был BORKED):

structure(list(clientid = 1:10, ProductA = structure(c(1L, 3L, 
2L, 2L, 3L, 1L, 3L, 2L, 1L, 1L), .Label = c("chair", "plate", 
"table"), class = "factor"), QuantityA = c(1L, 2L, 1L, 1L, 1L, 
1L, 2L, 3L, 1L, 2L), ProductB = structure(c(6L, 2L, 5L, NA, 3L, 
NA, 1L, 1L, NA, 4L), .Label = c("computer", "doll", "door", "plate", 
"shoes", "table"), class = "factor"), QuantityB = c(3L, 1L, 2L, 
NA, 2L, NA, 1L, 1L, NA, 1L)), .Names = c("clientid", "ProductA", 
"QuantityA", "ProductB", "QuantityB"), row.names = c(NA, -10L 
), class = "data.frame") 
+0

Похоже, что OP интересуется только тидиром, но это может представлять интерес для других. – Frank