我有一个大约15.000个用户ID的列表,
> head(ID_data)
[1] "A01Y" "AC43" "BBN5" "JK45" "NT66" "WC44"
和一个包含3列和大约100.000行的表作为data.table:
> head(USER_data)
V1 V2 V3
1: 0 John John
2: A01Y Martin 3311290
3: Peter Johnson Peter JK45 x
4: 1 wc44@email.com wc44@email.com
5: NA x
6: 419223 Christian 21221140 ac43@email.com
我想知道在3列中的某一列中包含用户ID的行的行索引。
在上面的示例中,代码应该找到第2,3,4和6行,因为它们在3列中的一列或多列中的某处包含“A01Y”,“JK45”,“WC44”和“AC43”。 / p>
主要问题是数据量很大。
我试过粘贴“|”在ID和使用grep之间搜索“A01Y | JK45”等:
toMatch <- paste(ID_data,collapse="|")
V1.matches <- grep(toMatch, USER_data$V1, ignore.case=TRUE)
V2.matches <- grep(toMatch, USER_data$V2, ignore.case=TRUE)
V3.matches <- grep(toMatch, USER_data$V3, ignore.case=TRUE)
但是grep只能采用大约2.500 ID的搜索模式,因此我必须以2500块的块来查看ID。这需要大约15分钟来计算。
我也尝试过使用strapplyc,它可以采用大约9.999 ID的搜索模式。
有没有更快的方法来查找行索引?
我正在考虑使用sqldf()并执行类似
的操作sqldf("SELECT * FROM USER_data, ID_data WHERE USER_data LIKE '%'+ID_data+'%'")
但我不确定该怎么做。
提前感谢任何建议。
答案 0 :(得分:0)
不确定这是否足够快,但我之前已经完成了很多行和ID。我花了一些时间,但不需要在块中处理ID。
# list of ids
IDs = c("A01Y", "AC43", "BBN5", "JK45", "NT66", "WC44")
# example dataframe
dt = data.frame(V1 = c("Christian 21223456","x", "wc44@email.com"),
V2 = c("0 John","1 wc44@email.com", "wc44@email.com"),
V3 = c("1","0","A01Y Martin 3311290"))
dt
# V1 V2 V3
# 1 Christian 21223456 0 John 1
# 2 x 1 wc44@email.com 0
# 3 wc44@email.com wc44@email.com A01Y Martin 3311290
# combine row elements in one big string
dt_rows = apply(dt, 1, function(x) paste(x,collapse = " "))
# update to lower case
IDs = tolower(IDs)
dt_rows = tolower(dt_rows)
# find in which row you have matches
sapply(IDs, grepl, dt_rows)
# a01y ac43 bbn5 jk45 nt66 wc44
# [1,] FALSE FALSE FALSE FALSE FALSE FALSE
# [2,] FALSE FALSE FALSE FALSE FALSE TRUE
# [3,] TRUE FALSE FALSE FALSE FALSE TRUE
# find which row id has a match (at least one match)
which(apply(sapply(IDs, grepl, dt_rows), 1, sum) >= 1)
# [1] 2 3