R 根据特定范围内的值分配data.table列值
所以我有两个数据表R 根据特定范围内的值分配data.table列值,r,join,merge,data.table,data-manipulation,R,Join,Merge,Data.table,Data Manipulation,所以我有两个数据表 size_categories = data.table(category = c("S", "M", "L"), size_min = c(0, 10, 25), size_max = c(10, 25, Inf), bin = c("blue", "red", "green"))
size_categories = data.table(category = c("S", "M", "L"), size_min = c(0, 10, 25),
size_max = c(10, 25, Inf), bin = c("blue", "red", "green"))
products = data.table(object_id = 1:10, size = seq(1, 37, 4))
我希望合并这些表,以便根据其大小为product表的每一行分配一个bin和size类别
我所知道的笨拙的方法是为产品的每一行指定一个类别,然后合并
products[size >= 0 & size < 10, category := "S"]
products[size >= 10 & size < 25, category := "M"]
products[size >= 25, category := "L"]
merge(products, size_categories)
产品[size>=0&size<10,类别:=“S”]
产品[尺寸>=10,尺寸<25,类别:=“M”]
产品[尺寸>=25,类别:=“L”]
合并(产品、大小和类别)
当然,这一点都不灵活,如果大小和类别发生变化,我将不得不重写它
我愿意使用其他软件包,但更喜欢只使用data.table的解决方案
谢谢 我会使用非等连接:
products[size_categories, `:=`(category = i.category, bin = i.bin),
on = .(size >= size_min, size < size_max)]
# > products
# object_id size category bin
# 1: 1 1 S blue
# 2: 2 5 S blue
# 3: 3 9 S blue
# 4: 4 13 M red
# 5: 5 17 M red
# 6: 6 21 M red
# 7: 7 25 L green
# 8: 8 29 L green
# 9: 9 33 L green
# 10: 10 37 L green
products[size\u categories,`:=`(category=i.category,bin=i.bin),
on=(大小>=大小\最小值,大小<大小\最大值)]
#>产品
#对象id大小类别箱
#1:1蓝色
#2:25 S蓝色
#3:39 S蓝
#4:4 13米红色
#5:517米红色
#6:6 21米红色
#7:725L绿色
#8:829L绿色
#9:933L绿色
#10:1037升绿色
以下是使用foverlaps
的方法供参考:
foverlaps(setkey(size_categories, size_min, size_max),
setkey(products[, size2 := size], size, size2))[, size2 := NULL][]
# object_id size category size_min size_max bin
# 1: 1 1 S 0 10 blue
# 2: 2 5 S 0 10 blue
# 3: 3 9 S 0 10 blue
# 4: 4 13 M 10 25 red
# 5: 5 17 M 10 25 red
# 6: 6 21 M 10 25 red
# 7: 7 25 M 10 25 red
# 8: 7 25 L 25 Inf green
# 9: 8 29 L 25 Inf green
# 10: 9 33 L 25 Inf green
# 11: 10 37 L 25 Inf green
如果“size_categories”表中有更多列需要包含在最终输出中,这可能会有所帮助。还有
foverlaps
,但我认为这需要复制一列并设置键+非常感谢!假设size_类别有更多的列,我想保留其中的大部分。我是否需要以类似的方式列出它们,还是有更快的方法?@paxton在这种情况下,连接比就地修改更合适。我希望我之前对类似问题的回答中的示例会有所帮助: