使用dplyr将一个data.frame输出到另一个data.frame

使用dplyr将一个data.frame输出到另一个data.frame,r,nested,dplyr,R,Nested,Dplyr,我有两个data.frames——一个查找表,告诉我一组中包含的一组产品。每组至少有一种1型和2型产品 第二个data.frame告诉我有关事务的详细信息。每笔交易可以有以下产品之一: a) 仅来自其中一组的类型1产品s b) 仅来自其中一组的2型产品s c) 同一组的1型和2型产品 对于我的分析,我感兴趣的是找出上面的c),即类型1和类型2(来自同一组)的产品销售了多少笔交易。如果在同一笔交易中销售的不同组的1类和2类产品,我们将完全忽略该交易 因此,类型1或类型2的每个产品必须属于同一组 这

我有两个data.frames——一个查找表,告诉我一组中包含的一组产品。每组至少有一种1型和2型产品

第二个data.frame告诉我有关事务的详细信息。每笔交易可以有以下产品之一:

a) 仅来自其中一组的类型1产品s

b) 仅来自其中一组的2型产品s

c) 同一组的1型和2型产品

对于我的分析,我感兴趣的是找出上面的c),即类型1和类型2(来自同一组)的产品销售了多少笔交易。如果在同一笔交易中销售的不同组的1类和2类产品,我们将完全忽略该交易

因此,类型1或类型2的每个产品必须属于同一组

这是我的查找表:

> P_Lookup
   Group ProductID1 ProductID2
  Group1          A          1
  Group1          B          2
  Group1          B          3
  Group2          C          4
  Group2          C          5
  Group2          C          6
  Group3          D          7
  Group3          C          8
  Group3          C          9
  Group4          E         10
  Group4          F         11
  Group4          G         12
  Group5          H         13
  Group5          H         14
  Group5          H         15 
例如,我不会在一个事务中包含产品G和产品15,因为它们属于不同的组

以下是交易记录:

  TransactionID ProductID ProductType
             a1         A           1
             a1         B           1
             a1         1           2
             a2         C           1
             a2         4           2
             a2         5           2
             a3         D           1
             a3         C           1
             a3         7           2
             a3         8           2
             a4         H           1
             a5         1           2
             a5         2           2
             a5         3           2
             a5         3           2
             a5         1           2
             a6         H           1
             a6        15           2
我的代码:

现在,我能够使用
dplyr
为一个组的入围交易编写代码。但是,我不确定如何为所有组矢量化我的代码

这是我的密码:

P_Groups<-unique(P_Lookup$Group)
Chosen_Group<-P_Groups[5]

P_Group_Ind <- P_Trans %>%
group_by(TransactionID)%>%
dplyr::filter((ProductID %in% unique(P_Lookup[P_Lookup$Group==Chosen_Group,]$ProductID1)) | 
(ProductID %in% unique(P_Lookup[P_Lookup$Group==Chosen_Group,]$ProductID2)) ) %>%
mutate(No_of_PIDs = n_distinct(ProductType)) %>%
mutate(Group_Name = Chosen_Group)

P_Group_Ind<-P_Group_Ind[P_Group_Ind$No_of_PIDs>1,]
以下是
p\u查找的
dput

structure(list(Group = c("Group1", "Group1", "Group1", "Group2", 
"Group2", "Group2", "Group3", "Group3", "Group3", "Group4", "Group4", 
"Group4", "Group5", "Group5", "Group5"), ProductID1 = c("A", 
"B", "B", "C", "C", "C", "D", "C", "C", "E", "F", "G", "H", "H", 
"H"), ProductID2 = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15)), .Names = c("Group", "ProductID1", "ProductID2"), row.names = c(NA, 
15L), class = "data.frame")

以下是将查找表中不存在的产品添加到p_Trans后的
dput()

> P_Lookup
   Group ProductID1 ProductID2
  Group1          A          1
  Group1          B          2
  Group1          B          3
  Group2          C          4
  Group2          C          5
  Group2          C          6
  Group3          D          7
  Group3          C          8
  Group3          C          9
  Group4          E         10
  Group4          F         11
  Group4          G         12
  Group5          H         13
  Group5          H         14
  Group5          H         15 
structure(list(TransactionID = c("a1", "a1", "a1", "a2", "a2", 
"a2", "a3", "a3", "a3", "a3", "a4", "a5", "a5", "a5", "a5", "a5", 
"a6", "a6", "a7"), ProductID = c("A", "B", "1", "C", "4", "5", 
"D", "C", "7", "8", "H", "1", "2", "3", "3", "1", "H", "15", 
"22"), ProductType = c(1, 1, 2, 1, 2, 2, 1, 1, 2, 2, 1, 2, 2, 
2, 2, 2, 1, 2, 3)), .Names = c("TransactionID", "ProductID", 
"ProductType"), row.names = c(NA, 19L), class = "data.frame")
下面是一个tidyverse(dplyr、tidyr和purrr)解决方案,我希望能有所帮助

请注意,在最后一行中使用
map_df
会将所有结果作为数据帧返回。如果您希望它成为每个组的列表对象,那么只需使用
map

library(dplyr)
library(tidyr)
library(purrr)

# Save unique groups for later use
P_Groups <- unique(P_Lookup$Group)

# Convert lookup table to product IDs and Groups
P_Lookup <- P_Lookup %>% 
              gather(ProductIDn, ProductID, ProductID1, ProductID2) %>% 
              select(ProductID, Group) %>% 
              distinct() %>% 
              nest(-ProductID, .key = Group)

# Bind Group information to transactions
# and group for next analysis
P_Trans <- P_Trans %>%
             left_join(P_Lookup) %>%
             filter(!map_lgl(Group, is.null)) %>%  
             unnest(Group) %>% 
             group_by(TransactionID)

# Iterate through Groups to produce results
map(P_Groups, ~ filter(P_Trans, Group == .)) %>% 
  map(~ mutate(., No_of_PIDs = n_distinct(ProductType))) %>% 
  map_df(~ filter(., No_of_PIDs > 1))
#> Source: local data frame [12 x 5]
#> Groups: TransactionID [4]
#> 
#>    TransactionID ProductID ProductType  Group No_of_PIDs
#>            <chr>     <chr>       <dbl>  <chr>      <int>
#> 1             a1         A           1 Group1          2
#> 2             a1         B           1 Group1          2
#> 3             a1         1           2 Group1          2
#> 4             a2         C           1 Group2          2
#> 5             a2         4           2 Group2          2
#> 6             a2         5           2 Group2          2
#> 7             a3         D           1 Group3          2
#> 8             a3         C           1 Group3          2
#> 9             a3         7           2 Group3          2
#> 10            a3         8           2 Group3          2
#> 11            a6         H           1 Group5          2
#> 12            a6        15           2 Group5          2
库(dplyr)
图书馆(tidyr)
图书馆(purrr)
#保存唯一组以供以后使用
P_组%
选择(产品ID,组)%>%
不同的()%>%
嵌套(-ProductID,.key=Group)
#将组信息绑定到事务
#并分组进行下一步分析
P_Trans%
左联合(P\U查找)%>%
筛选器(!map_lgl(组,is.null))%>%
unnest(组)%%>%
分组人(交易ID)
#遍历组以生成结果
映射(P_组,~filter(P_Trans,Group==)%>%
映射(~变异(,PIDs的编号=n不同(ProductType))%>%
map_df(~过滤器(,PIDs数量>1))
#>来源:本地数据帧[12 x 5]
#>组:TransactionID[4]
#> 
#>TransactionID ProductID ProductType组编号为
#>                                
#>1 a1 A 1组1 2
#>2 a1 B 1组1 2
#>3 a1 1 2组1 2
#>4 a2 C1组2 2
#>5 a2 4 2组2 2
#>6 a2 5 2组2 2
#>7 a3 D 1组3 2
#>8 a3 C1组3 2
#>9 a3 7 2组3 2
#>10 a3 8 2组3 2
#>11 a6 H 1组5 2
#>12 a6 15 2组5 2

这里有一个单管
dplyr
解决方案:

P_DualGroupTransactionsCount <- 
    P_Lookup %>% # data needing single column map of Keys
    gather(IDnum, ProductID, ProductID1:ProductID2) %>% # produce long single map of Keys for GroupID (tidyr::)
    right_join(P_trans) %>% # join transactions to groupID info
    group_by(TransactionID, Group) %>% # organize for same transaction & same group
    mutate(DualGroup = ifelse(n_distinct(ProductType)==2, T, F)) %>% # flag groups with both groups in a single transaction
    filter(DualGroup == T) %>% # choose only doubles
    select(TransactionID, Group) %>% # remove excess columns
    distinct %>%  # remove excess rows
    nrow # count of unique transaction ID's

# P_DualGroupTransactions
# Source: local data frame [4 x 2]
# Groups: TransactionID, Group [4]
#     
# TransactionID  Group
#           <chr>  <chr>
# 1            a1 Group1
# 2            a2 Group2
# 3            a3 Group3
# 4            a6 Group5


# P_DualGroupTransactionsCount
 [1] 4
P_DualGroupTransactionCount%#需要单列键映射的数据
聚集(IDnum、ProductID、ProductID1:ProductID2)%>%#为GroupID(tidyr::)生成键的长单映射
右键连接(P_trans)%>%#将事务连接到groupID信息
分组依据(TransactionID,group)%>%#为同一事务和同一组组织
mutate(DualGroup=ifelse(n_distinct(ProductType)==2,T,F))%>%#在单个事务中标记两个组的组
过滤器(双组==T)%>%#仅选择双组
选择(TransactionID,组)%>%#删除多余的列
独特%>%#删除多余的行
nrow#唯一事务ID的计数
#P_DualGroupTransactions
#来源:本地数据帧[4 x 2]
#组:TransactionID,组[4]
#     
#事务ID组
#             
#1 a1组1
#2 a2组2
#3 a3组3
#4 a6组5
#P_DualGroupTransactionCount
[1] 4

这是一个极好的回答。我是一个初学者,所以我有一个简单的问题:你能解释一下为什么你做了
变异(I=1:n())
as\u data\u frame()
。我试着在没有这两行代码的情况下运行代码,效果很好。所以,我很好奇。好的,抓住了望塔!那些台词只是在我前进的过程中帮我把事情弄清楚。我已经从答案中删除了它们。谢谢你的澄清。我有一个简单的问题——我的原始数据集
P_Trans
有一些
ProductID
s,它们不在查找表
P_Lookup
中。在这种情况下,我得到了这个错误:每一列必须是向量列表或数据帧列表[Group]
。我是一个初学者,所以我不知道如何解决这个问题。你能帮我吗?根据SO的策略,我不想创建新线程。我在帖子中添加了
dput()
。我衷心感谢你的帮助help@watchtower谢谢你的接受。我做了一个更改,将删除未包含在查找表中的所有产品:
过滤器(!map\u lgl(Group,is.null))
。这在绑定到
P\u Trans
时发生。