【问题标题】:R data.table subsetting on multiple conditions.多个条件下的 R data.table 子集。
【发布时间】:2013-11-20 03:45:07
【问题描述】:

使用下面的数据集,如果该客户曾经购买过 SKU 1,我如何编写一个 data.table 调用来对该表进行子集化并返回该客户的所有客户 ID 和相关订单?

预期结果应返回一个表,在该条件下排除 cid 3 和 5 以及匹配 sku==1 的客户的每一行。

我被卡住了,因为我不知道如何编写“包含”语句,== 文字只返回 sku 的匹配条件...我相信有更好的方法..

library("data.table")    
df<-data.frame(cid=c(1,1,1,1,1,2,2,2,2,2,3,4,5,5,6,6),
    order=c(1,1,1,2,3,4,4,4,5,5,6,7,8,8,9,9),
    sku=c(1,2,3,2,3,1,2,3,1,3,2,1,2,3,1,2))

    dt=as.data.table(df)

【问题讨论】:

  • 使用cid %in% c(3,5) 测试“包含”。

标签: r data.table


【解决方案1】:

这类似于previous answer,但这里的子集以更类似于data.table 的方式工作。

首先,让我们选择符合我们条件的cids:

matching_cids = dt[sku==1, cid]

%in% 运算符允许我们过滤到列表中包含的那些项目。所以,使用上面的:

dt[cid %in% matching_cids]

或单行:

> dt[cid %in% dt[sku==1, cid]]
     cid order sku
  1:   1     1   1
  2:   1     1   2
  3:   1     1   3
  4:   1     2   2
  5:   1     3   3
  6:   2     4   1
  7:   2     4   2
  8:   2     4   3
  9:   2     5   1
 10:   2     5   3
 11:   4     7   1
 12:   6     9   1
 13:   6     9   2

【讨论】:

  • 谢谢彼得!这是我试图解决的问题,1 行,简单优雅,太棒了!
【解决方案2】:

我会认为使用keys更多 (?!) data.table。我无法完全弄清楚如何将全部内容放在一行中,但我认为这在大数据上会更快一些,因为我理解(我很可能弄错了)这是迄今为止唯一避免矢量扫描的解决方案(与二分搜索相比速度很慢):

#  Set initial key
setkey(dt,sku)

#  Select only rows with 1 in the sku and return first example of each, setting key to customer id
dts <- dt[ J(1) , .SD[1] , keyby = cid ]

#  change key of dt to cid to match customer id
setkey(dt,cid)

#  join based on common key
dt[dts,.SD]
#    cid order sku
# 1:   1     1   1
# 2:   1     1   2
# 3:   1     2   2
# 4:   1     1   3
# 5:   1     3   3
# 6:   2     4   1
# 7:   2     5   1
# 8:   2     4   2
# 9:   2     4   3
#10:   2     5   3
#11:   4     7   1
#12:   6     9   1
#13:   6     9   2

您可以在一行中执行的另一种方法是使用 data.table merge 像这样...

setkey(dt,sku)
merge( dt[ J(1) , .SD[1] , keyby = cid ] , dt , by = "cid" )

【讨论】:

  • 不确定这个答案的 -1 是什么,但我要指出的一件事是,如果另一个答案中的矢量扫描速度更快,我会感到非常惊讶,原因有两个- 首先,只有当数据已经被键入或者向量扫描内部有很多评估时,加入才会更快,并且两个 - 以这种方式使用.SD(它会导致在[.data.table 内部调用[.data.table ) 目前很慢
猜你喜欢
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2013-01-08
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2020-07-22
相关资源
最近更新 更多