我在两个不同的表(100万行* 15; 3000 * 20)中可能会获得更大的(1000万行)多重匹配问题。对于大数据,在不同的行和列中进行多个匹配
我的解决方案可行,但我想尽可能快地考虑到我可能需要在更大的数据框中使用脚本。我正在使用r软件包data.table。
考虑两个例子的表,其中没有行可以被删除:
表1 - 的ToMach柱等于FALSE意味着相关联的标签不存在于表2,该步骤降低由两个顺序匹配到的大小执行:
set.seed(99)
table1 <- data.table(Tag = sample(paste0("tag_",1:3), 5, replace = T))
table1[ , ToMatch := ifelse(Tag == "tag_1", F, T)]
table1
Tag ToMatch
1: tag_2 TRUE
2: tag_1 FALSE
3: tag_3 TRUE
4: tag_3 TRUE
5: tag_2 TRUE
表2:
set.seed(99)
table2 <- data.table(center = sample(paste0("tag_",2:8), 5, replace = T),
north = sample(paste0("tag_",2:8), 5, replace = T),
south = sample(paste0("tag_",2:8), 5, replace = T))
> table2
center north south
1: tag_6 tag_8 tag_5
2: tag_2 tag_6 tag_5
3: tag_6 tag_4 tag_3
4: tag_8 tag_4 tag_6
5: tag_5 tag_3 tag_6
我的目标是找到表2表1哪里的标签被发现的行(可在以上各列的任何一列中)。我想输出为列表:
输出:
Tag ToMatch output
1: tag_2 TRUE 2
2: tag_1 FALSE NA
3: tag_3 TRUE 3,5
4: tag_3 TRUE 3,5
5: tag_2 TRUE 2
我的解决办法:
什么表1的行是评估
match.index <- which(table1$ToMatch == T)
> match.index
[1] 1 3 4 5
池中的所有标签从表2中维护排序。使用t
(tag_6 tag_8 tag_5 tag_2 tag_6 tag_5 ...
)
all.tags <- as.vector(t(table2))
> all.tags
[1] "tag_6" "tag_8" "tag_5" "tag_2" "tag_6" "tag_5" "tag_6"
[8] "tag_4" "tag_3" "tag_8" "tag_4" "tag_6" "tag_5" "tag_3"
[15] "tag_6"
预定义的空列表
list.results <- as.list(rep(as.numeric(NA), dim(table1)[1]))
循环:
for (i in 1:length(match.index)) {
list.results[[ match.index[i] ]] <- ceiling(
grep(table1[match.index[i], Tag], all.tags)
/3)
}
# dividing the index of all.tags found with grep by 3 (the original
# number of columns in table2) and rounding up to the closest integer
# (ceiling) return the index of the original table 2 where the tag
# is located
最终输出:
> table1[ , output := list.results]
> table1
Tag ToMatch output
1: tag_2 TRUE 2
2: tag_1 FALSE NA
3: tag_3 TRUE 3,5
4: tag_3 TRUE 3,5
5: tag_2 TRUE 2
你有什么建议,以加快这一代码?
预先感谢您
任何好的理由,表1中的重复行?如果您对速度感兴趣,那么这种数据结构决策可能是一个减速带。同样,使用'melt(table2 [,r:= .I],“r”,value.name =“Tag”)可以更好地实现表格2的宽格式存储...... – Frank
@Frank,上表是具有更多字段的较大表格的快照。在现实中,没有行将被复制 –