根据多个条件分配ID

时间:2017-08-02 14:17:45

标签: r

我是R的新手,我正在尝试整理一个脚本来自动执行现在非常手动的三角测量不同报告的任务。

在我的工作中,我收到来自不同来源的报告,如果需要,我需要进行三角测量和汇总。为了简化(和匿名)我的例子,让我说我得到了市场上不同商家的销售报告。此数据包括“观察员”,“卖方”,“买方”和“销售日期”。

示例:

market <- data.frame(observer=c("Tom", "Fred", "Hank", "Tom"), 
seller=c("A", "A", "B", "A"),
buyer=c("X", "X", "Y", "X"),
date_sale=c("2017/01/01", "2017/01/03", "2017/01/04", "2017/01/05"))

现在,其中一些数据可能会重叠,因此我需要确保在相似的时间段(+/- 7天)内已经跨商家报告了交易,并为其分配了相同的ID(所以后来我可以合并两个)。但是,如果同一个观察者在不久之后再次报告相同的交易,我可以假设在这种情况下它是一个单独的交易。

在我的例子中,我可以看到汤姆和弗雷德都报告了在两天之内从A到X的购买,而汤姆在同一时期报告了第二个。因此,理想情况下,R应该为前两个事务提供相同的ID,并为第三个事务分别提供一个ID。

结果应为:

market <- data.frame(observer=c("Tom", "Fred", "Hank", "Tom"), 
seller=c("A", "A", "B", "A"),
buyer=c("X", "X", "Y", "X"),
date_sale=c("2017/01/01", "2017/01/03", "2017/01/04", "2017/01/05"),
id=c(1, 1, 2, 3))

我尝试使用getanID包中的splitstackshape,但我无法找到如何在“早期交易的+/- 7天内”提供参数。我对任何建议都持开放态度,非常感谢你!

1 个答案:

答案 0 :(得分:1)

为了完整起见,我在您的data.frame中添加了另一个数据点,距离超过7天。我还将您的日期转换为正确的类以简化日期算术:

market <- data.frame(observer=c("Tom", "Fred", "Hank", "Tom", "Joe"),
                 seller=c("A", "A", "B", "A", "A"),
                 buyer=c("X", "X", "Y", "X", "X"),
                 date_sale=as.Date(c("2017/01/01", "2017/01/03",
                        "2017/01/04","2017/01/05", "2017/01/09")) )

您要做的第一步是将数据存入7天的垃圾箱:

library( dplyr )    # We'll make extensive use of this package
m1 <- market %>% mutate( date_bin = as.integer((date_sale - min(date_sale)) / 7) )
#   observer seller buyer  date_sale date_bin
# 1      Tom      A     X 2017-01-01        0
# 2     Fred      A     X 2017-01-03        0
# 3     Hank      B     Y 2017-01-04        0
# 4      Tom      A     X 2017-01-05        0
# 5      Joe      A     X 2017-01-09        1  

最终ID将是两个“子ID”的产物:外部ID来自对date_binsellerbuyer对您的数据进行分组(即,什么是可以在7天内发生的所有可能的交易版本),以及内部ID,它列举了由每个组中的同一观察者做出的重复交易。

可以按如下方式计算两个ID:

i1 <- m1 %>% group_by( date_bin, seller, buyer ) %>% group_indices()
m2 <- m1 %>% mutate( outID = i1 ) %>% group_by( outID, observer ) %>%
        mutate( inID = 1:n() )
#   observer seller buyer  date_sale date_bin outID inID
# 1      Tom      A     X 2017-01-01        0     1    1
# 2     Fred      A     X 2017-01-03        0     1    1
# 3     Hank      B     Y 2017-01-04        0     2    1
# 4      Tom      A     X 2017-01-05        0     1    2
# 5      Joe      A     X 2017-01-09        1     3    1 

最后,我们从outIDinID的所有唯一对中创建最终ID:

market %>% mutate( id = group_by( m2, outID, inID ) %>% group_indices() )
#   observer seller buyer  date_sale id
# 1      Tom      A     X 2017-01-01  1
# 2     Fred      A     X 2017-01-03  1
# 3     Hank      B     Y 2017-01-04  3
# 4      Tom      A     X 2017-01-05  2
# 5      Joe      A     X 2017-01-09  4

请注意,索引与您在问题中请求的顺序不完全相同,但由于这些是任意整数,因此您可以将它们重新分配给所需的值,而不会失去一般性。