轻松检查其他变量中是否记录了objective?

Easily check whether an objective was recorded in other variable?

我有客户 ID,product_id1 和 product_id2。数据有客户的购买信息,并按客户和时间排序,因此每个客户的第一行是最旧的记录。
product_id1 包括购买的物品 product_id2 包含我想知道每件商品之前是否购买过的商品(从 product_id1 查询)。

对于每个客户 product_id2 中的每个项目,我想创建一个虚拟变量来指示 product_id2 中的每个项目是否在过去购买过
换句话说, product_id2 中第 n 行的值在 product_id1 的第 1~(n-1) 行中至少显示一次,purchased_before 为 1,否则为 0。

所以我想创建 "purchased_before" 列。

我可以使用 for 循环来完成,但是有什么有效的方法吗?

数据如下,

customer id      product_id1   product_id2     purchased_before
    1             112             113                 0
    1             115             114                 0
    1             113             113                 0
    1             114             113                 1
    1             115             114                 1
    ....
    2             112             115                 0
    2             115             112                 1
    2             113             113                 0

尝试以下操作:

dplyr:

df %>%
    group_by(customer_id) %>%
    mutate(purchased_before = sapply(row_number(), function(x) {
               ifelse(product_id2[x] %in% product_id1[1:(x-1)], 1, 0)
           })
    )

base R:

do.call(rbind, lapply(split(df, df$customer_id), function(x) {
    x$purchased_before <- sapply(seq_len(nrow(x)), function(y) {
        ifelse(x$product_id2[y] %in% x$product_id1[1:(y-1)], 1, 0)
    })
    x
}))

这里的主要内容是遍历 product_id2 列中的行号,并使用这些行号访问给定索引处的 product_id2 值以及 product_id1 值从 1 到给定的索引。获得这些值后,您可以在 ifelse 中执行简单的 match 运算符。如果匹配,则分配 1;或者 0 否则。

希望这有用。

这可以使用 非等值连接 并在连接时聚合来解决:

library(data.table)
setDT(DT)[
  # add "time variable", i.e., row id to identify earlier purchases
  , rn := .I][
    # create new column with ...
    , cnt_of_earlier_purchases := 
      # ... the result of the non-equi join aggregate
      DT[DT, on = .(customer_id, product_id1 = product_id2, rn < rn), .N, by = .EACHI]$N][]

   customer_id product_id1 product_id2 rn cnt_of_earlier_purchases
1:           1         112         113  1                        0
2:           1         115         114  2                        0
3:           1         113         113  3                        0
4:           1         114         113  4                        1
5:           1         115         114  5                        1
6:           2         112         115  6                        0
7:           2         115         112  7                        1
8:           2         112         113  8                        0
9:           2         115         112  9                        2

新列包含实际购买前的购买次数。

请注意,已使用修改后的包含多次购买的示例数据集来演示计算购买的效果。

或者,可以附加一个逻辑值而不是计数:

setDT(DT)[, rn := .I][
  , purchased_before := 
    DT[DT, on = .(customer_id, product_id1 = product_id2, rn < rn), .N, by = .EACHI]$N > 0][]
   customer_id product_id1 product_id2 rn purchased_before
1:           1         112         113  1            FALSE
2:           1         115         114  2            FALSE
3:           1         113         113  3            FALSE
4:           1         114         113  4             TRUE
5:           1         115         114  5             TRUE
6:           2         112         115  6            FALSE
7:           2         115         112  7             TRUE
8:           2         112         113  8            FALSE
9:           2         115         112  9             TRUE

数据

library(data.table)
DT <- fread(
"customer_id      product_id1   product_id2     purchased_before
    1             112             113                 0
    1             115             114                 0
    1             113             113                 0
    1             114             113                 1
    1             115             114                 1
    2             112             115                 0
    2             115             112                 1
    2             112             113                 0
    2             115             112                 0", select = 1:3)