2015-08-05 4 views
0

У меня есть 2 таблицы, «сделки» с более чем 500M строк и «Клиенты» над 3M рядамиUpdate dataframe из другого dataframe

data <- data.frame(Trans = c(1,2,3,4,5), Cust01 = c("A","B","C","D","F"), 
        Cust02 = c("S","E","","TE","F"), Cust03 = c("F","","D","","F")) 

cust_type <-data.frame(Cust = c("A","B","C","D"), Type = c("1","2","3","4")) 

dataresult <- data.frame(Trans = c(1,2,3,4,5), 
         Cust01 = c("A","B","C","D","F"), 
         Cust01Type = c("1","2","3","4","5"), 
         Cust02 = c("S","E","","TE","F"), 
         Cust02Type = c("","","","",""), 
         Cust03 = c("F","","D","","F"), 
         Cust03Type = c("","","4","","")) 

Я хотел бы добавить тип клиента к данным эффективным способом. Обычно с sql Я буду использовать несколько левых соединений, я пробовал это с dplyr, но навсегда. Я также попытался использовать %in% с логическим возвратом, а затем цикл, чтобы сосредоточиться на истинных значениях. Знает ли кто-нибудь лучший способ сделать это?

ответ

1

Если вам нужна быстрая производительность, ничто не сравнится с пакетом data.table (пока). Поскольку данные транзакций теперь в широком формате, первый шаг - преобразовать его в длинный формат. Это упростит процесс обработки.

library(data.table) #v1.9.5 
trans_data <- melt(setDT(data), id.vars = "Trans", 
        variable.name = "Cust",    # set name variable column 
        variable.factor = TRUE,    # set as a factor variable instead of a character variable 
        value.name = "Cvalue")[!Cvalue==""] # set name value column & remove empty cases 

Когда вы сделаете это, вы можете присоединиться к двум DataTables:

# set the keys by which you are joining 
setDT(trans_data, key = "Cvalue") 
setDT(cust_type, key = "Cust") 

# join the customer type into the transaction data 
trans_data[cust_type, Ctype:=Type] 

это дает:

> trans_data 
    Trans Cust Cvalue Ctype 
1:  1 Cust01  A  1 
2:  2 Cust01  B  2 
3:  3 Cust01  C  3 
4:  4 Cust01  D  4 
5:  3 Cust03  D  4 
6:  2 Cust02  E NA 
7:  5 Cust01  F NA 
8:  5 Cust02  F NA 
9:  1 Cust03  F NA 
10:  5 Cust03  F NA 
11:  1 Cust02  S NA 
12:  4 Cust02  TE NA 

Если вы хотите изменить порядок в результате data.table, вы может сделать это, например, с помощью:

setorder(trans_data, Trans, Cust) 

или все сразу с:

trans_data <- trans_data[cust_type, Ctype:=Type][order(Trans,Cust)] 

, который дает:

> trans_data 
    Trans Cust Cvalue Ctype 
1:  1 Cust01  A  1 
2:  1 Cust02  S NA 
3:  1 Cust03  F NA 
4:  2 Cust01  B  2 
5:  2 Cust02  E NA 
6:  3 Cust01  C  3 
7:  3 Cust03  D  4 
8:  4 Cust01  D  4 
9:  4 Cust02  TE NA 
10:  5 Cust01  F NA 
11:  5 Cust02  F NA 
12:  5 Cust03  F NA 

Примечание: Я использовал development version of data.table, с которым он не нужен больше, чтобы загрузить reshape2 пакет для функция melt.

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