You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于relations子集匹配值筛选objects数据表的技术问题

筛选满足「周长与ID=4对象共享边界之差小于180」的对象

数据定义

library(data.table)

objects <- data.table("ID" = c(5,4,3,2,1), "Perimeter" = c(500,400,300,200,100))
# objects数据表:
#    ID Perimeter
# 1:  5       500
# 2:  4       400
# 3:  3       300
# 4:  2       200
# 5:  1       100

relations <- data.table("ID.x" = c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5), 
                        "ID.y" = c(2,3,4,5,1,3,4,5,1,2,4,5,1,2,3,5,1,2,3,4), 
                        "Border" = c(20,40,60,80,20,70,10,60,40,70,150,20,60,10,150,90,80,60,20,90))
# relations数据表:
#    ID.x ID.y Border
# 1:    1    2     20
# 2:    1    3     40
# 3:    1    4     60
# 4:    1    5     80
# 5:    2    1     20
# 6:    2    3     70
# 7:    2    4     10
# 8:    2    5     60
# 9:    3    1     40
#10:    3    2     70
#11:    3    4    150
#12:    3    5     20
#13:    4    1     60
#14:    4    2     10
#15:    4    3    150
#16:    4    5     90
#17:    5    1     80
#18:    5    2     60
#19:    5    3     20
#20:    5    4     90

需求说明

筛选出所有Perimeter减去与ID=4的对象的共享Border长度小于180的对象,预期结果为ID=1和ID=3的对象。

错误尝试分析

最初尝试的代码因长度不匹配报错:

objects[ID!=4][Perimeter - relations[ID.x==4 & ID.y==ID]$Border < 180]

错误信息:

Error: RHS of == is length 4 which is not 1 or nrow (20). For robustness, no recycling is allowed (other than of length 1 RHS). Consider %in% instead.

改用%in%后,因relations返回的行顺序与objects[ID!=4]的顺序不匹配,导致Border值对应错误:

print(objects[ID!=4][, border_length_with_obj_4 := relations[ID.x==4 & ID.y%in%ID]$Border])
#    ID Perimeter border_length_with_obj_4
# 1:  5       500                       60  # 应为90
# 2:  3       300                       10  # 应为150
# 3:  2       200                      150  # 应为10
# 4:  1       100                       90  # 应为60

最终得到错误的筛选结果。

正确解法

方法1:合并数据表后筛选

先从relations中提取ID=4对应的边界数据,再与objects关联,确保ID与Border值一一对应:

# 提取ID=4作为ID.x时的边界数据,重命名ID.y为ID
border_with_4 <- relations[ID.x == 4, .(ID = ID.y, Border_with_4 = Border)]
# 关联objects(排除ID=4)与border_with_4
result <- objects[ID != 4][border_with_4, on = "ID"]
# 筛选满足条件的行,保留ID和Perimeter列
result[Perimeter - Border_with_4 < 180, .(ID, Perimeter)]

方法2:按ID分组匹配边界值

通过by=ID分组,为每个ID匹配对应的Border值后筛选:

objects[ID != 4][, 
  .(ID, Perimeter, Border_with_4 = relations[ID.x == 4 & ID.y == .BY$ID, Border]), 
  by = ID
][Perimeter - Border_with_4 < 180, .(ID, Perimeter)]

预期输出

ID Perimeter
1:  3       300
2:  1       100

内容的提问来源于stack exchange,提问作者Wander Demuynck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:33:15