【发布时间】:2017-08-17 18:40:32
【问题描述】:
我有两个数据框:
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
这是一个购物篮分析。 df1 是购买了列出的每个项目的客户/合作伙伴:A、B、C...等。
df2 是与过去购买的物品相关的推荐。
每个 df2 行中的最后一个值代表建议。因此,从最后一个非 NA 值开始的每一行中的前面值是“篮子”。
所以比如df2的第一行,就是说:如果B和A一起买,推荐G。
我希望能够确定 df1 的每个合作伙伴是否购买了每一行中的所有值,不包括最终值,因为这是建议。然后将该建议添加到新数据框每一行的末尾。
例如: 合伙人:Alpha,从第一行推荐价值G好不好?答案是肯定的,因为他们从 df2(A 和 B)中的该行购买了所有值。
对于合作伙伴:Beta,建议值 G 并不好,因为并非 df2 第一行的所有值都可以在 Beta 行中找到。
最终输出:
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
为清楚起见写出结果:
df3
row1 输出“No”,因为在 Alpha Partner 中找不到 G,并且 G 之前的所有值都显示在 Alpha Partner (B,A) 中
row2 输出“是”,因为在 Alpha 合作伙伴中找到了 D,并且 D 之前的所有值都显示在 Alpha 合作伙伴 (B,A) 中
第 3 行输出“是”,因为在 Alpha 合作伙伴中找到了 D,并且 D 之前的所有值都显示在 Alpha 合作伙伴(A、B、C)中
row4 输出“No”,因为在 Alpha Partner 中找不到 M,并且 M 之前的所有值都显示在 Alpha Partner (C,A) 中
row5 输出“No”,因为在 Zeta Partner 中找不到 E,并且 E 之前的所有值都显示在 Zeta Partner (K,M) 中
row6 输出“No”,因为在 Zeta Partner (M) 中找不到 T,并且 T 之前的所有值都显示在 Zeta Partner (M) 中
row7 输出“Yes”,因为在 Zeta Partner 中找到了 M,并且 M 之前的所有值都显示在 Zeta Partner (K) 中
我认为这必须是某种连接或匹配,但不知道该怎么做。
如果有人能帮我解决这个问题,这将非常有帮助。
谢谢。
这是一次尝试:
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])
但这不起作用,因为它没有考虑所有值,只有当其中一个匹配时......不是全部。
【问题讨论】:
-
dput的一些示例数据会有所帮助。 -
@dash2 刚开始提供了数据结构,谢谢!
-
我不明白为什么 'lift' 的第 11 行被删除了
-
这是因为在 df1 行之一中未找到所有 D、C、M。逻辑是,如果在 df1 中找到最后一个非 na 值之前的 df2 中的所有内容,则它是匹配的。在这种情况下,最后一个非 na 值是 K。这就是我在上一篇文章中思考的原因,我需要删除最后一个非 NA 值,进行匹配,然后稍后使用与它。 @akrun
-
我还在这里问了这个问题的一个更简单的版本:stackoverflow.com/questions/43018385/…
标签: r join data.table dplyr melt