Corresponder quadros de dados, excluindo o último valor que não seja NA e desconsiderando o pedido
Eu tenho dois quadros de dados:
Partner<-c("Alpha","Beta","Zeta")
COL1<-c("A","C","M")
COL2<-c("B","D","K")
COL3<-c("C","F",NA)
COL4<-c("D",NA,NA)
df1<-data.frame(Partner,COL1,COL2,COL3,COL4)
lift<-c(9,10,11,12,12,23,12,24)
RULE1<-c("B","B","D","A","C","K","M","K")
RULE2<-c("A","A","C","B","A","M","T","M")
RULE3<-c("G","D","M","C" ,"M", "E",NA,NA)
RULE4<-c(NA,NA,"K","D" ,NA, NA,NA,NA)
df2<-data.frame(lift,RULE1,RULE2,RULE3,RULE4)
df1
Partner COL1 COL2 COL3 COL4
Alpha A B C D
Beta C D F NA
Zeta M K NA NA
df2
lift RULE1 RULE2 RULE3 RULE4
9 B A G NA
10 B A D NA
11 D C M K
12 A B C D
12 C A M NA
23 K M E NA
12 M T NA NA
24 K M NA NA
Esta é uma análise da cesta de mercado. df1 é o cliente / parceiro que comprou cada um dos itens listados: A, B, C ... etc.
df2 são as recomendações associadas aos itens comprados no passado.
O último valor em cada uma das linhas df2 representa a recomendação. Portanto, os valores anteriores em cada linha do último valor não-NA são os "cestos".
Portanto, por exemplo, na primeira linha do df2, é declarado: Se B e A forem comprados juntos, recomende G.
Quero descobrir se cada parceiro do DF1 comprou TODOS os valores em cada linha, excluindo o valor final, já que essa é a recomendação. Em seguida, adicione essa recomendação ao final de cada linha do novo quadro de dados.
Por exemplo: Para o parceiro: Alpha, seria bom recomendar o valor G da primeira linha? A resposta seria sim, porque eles compraram todos os valores dessa linha no df2 (A e B).
Para o parceiro: Beta, não seria bom recomendar o valor G, porque nem todos os valores da primeira linha do df2 são encontrados na linha Beta.
Saída final:
Partner COL1 COL2 COL3 COL4 lift RULE1 RULE2 RULE3 RULE4 Does Last Non-NA Value Exist in Row?
Alpha A B C D 9 B A G NA No
Alpha A B C D 10 B A D NA Yes
Alpha A B C D 12 A B C D Yes
Alpha A B C D 12 C A M NA No
Zeta M K NA NA 23 K M E NA No
Zeta M K NA NA 12 M T NA NA No
Zeta M K NA NA 24 K M NA NA Yes
Resultados escritos para maior clareza:
df3
a linha1 gera "Não" porque G não é encontrado no Alpha Partner e todos os valores antes de G aparecem no Alpha Partner (B, A)
a linha2 gera "Sim" porque D é encontrado no Alpha Partner e todos os valores antes de D aparecem no Alpha Partner (B, A)
a linha3 gera "Sim" porque D é encontrado no Alpha Partner e todos os valores antes de D aparecem no Alpha Partner (A, B, C)
a linha4 gera "Não" porque M não é encontrado no Alpha Partner e todos os valores antes de M aparecem no Alpha Partner (C, A)
row5 gera "Não" porque E não é encontrado no Zeta Partner e todos os valores anteriores a E aparecem no Zeta Partner (K, M)
row6 gera "Não" porque T não é encontrado no Zeta Partner e todos os valores antes de T aparecem no Zeta Partner (M)
row7 gera "Sim" porque M é encontrado no Zeta Partner e todos os valores antes de M aparecem no Zeta Partner (K)
Eu acho que tem que ser uma junção ou uma partida de algum tipo, mas não consigo descobrir como fazê-lo.
Isso seria extremamente útil se alguém pudesse me ajudar com isso.
Obrigado.
Esta foi a tentativa:
df1<-cbind(df1_id=1:nrow(df1),df1)
df2 <- cbind(df2_id=1:nrow(df2),df2)
d11 <- df1 %>% gather(Col, Value,starts_with("C")) #Long
d11 <- d11 %>% na.omit() %>%group_by(df1_id) %>% slice(-n()) #remove last non NA
d22 <- df2 %>% gather(Rule, Value,starts_with("R"))
res <- inner_join(d11,d22)
rm(d22)
rm(d11)
final<-cbind(df1[res$df1_id,],df2[res$df2_id,])
final$Exist <- apply(final, 1, FUN = function(x)
c("No", "Yes")[(anyDuplicated(x[!is.na(x) & x != "" ])!=0) +1])
Mas isso não funcionou porque não levou em consideração todos os valores, apenas se um deles corresponder ... nem todos.