Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-根据多个列表中的一个列表的匹配项为向量赋值_R_Performance - Fatal编程技术网

R-根据多个列表中的一个列表的匹配项为向量赋值

R-根据多个列表中的一个列表的匹配项为向量赋值,r,performance,R,Performance,我有一个包含文本字符串的向量的数据帧。我试图根据每个字符串是否包含在多个列表中的一个列表中,将这些字符串重新编码为一个值(0,1,2,…),并在数据帧中分配给一个新向量 例如: vector = c( "A", "B", "C", "D", "E") list1 = c("B", "G", "P", "Z") list2 = c("A", "E", "M", "Q") list3 = everything not in list1 or list2 根据向量[i]是否包含在列表1、列表2或列表

我有一个包含文本字符串的向量的数据帧。我试图根据每个字符串是否包含在多个列表中的一个列表中,将这些字符串重新编码为一个值(0,1,2,…),并在数据帧中分配给一个新向量

例如:

vector = c( "A", "B", "C", "D", "E")
list1 = c("B", "G", "P", "Z")
list2 = c("A", "E", "M", "Q")
list3 = everything not in list1 or list2
根据向量[i]是否包含在列表1、列表2或列表3中,新向量应分配“0”、“1”或“2”:

new_vector = (2, 1, 3, 3, 2)
我尝试了各种%in%的排列,但问题是“vector”非常长(数十万个元素),我匹配的一些列表也相当长(10-30个元素)。我有一些有效的语句,但速度非常慢。看着苔藓慢慢生长


要以最佳方式加速这种复杂的匹配场景,R的“窍门”是什么?

首先,您应该将列表存储在单个对象中,而不是使用编号的名称:

L = list(list1, list2)
然后可以使用data.table进行快速匹配:

library(data.table)
LDT = rbindlist(lapply(L, data.table), idcol = TRUE)
vDT = data.table(v = vector)

vDT[, id := LDT[vDT, on=.(V1 = v), .id]]

#    v id
# 1: A  2
# 2: B  1
# 3: C NA
# 4: D NA
# 5: E  2
没有必要为“不在其他列表中的所有内容”创建一个列表。它可以被分配为NA,如下所示

如果您的列表不是不相交的,这将以奇怪的方式中断,因此如果是这种情况,您可能需要设置一个规则来停止:

stopifnot( !anyDuplicated(LDT[, "V1"]) )

工作原理

LDT和vDT是表,联接的语法是
x[i,on=,j]
。联接使用
i
查找
x
中的行
j
是使用匹配行计算的某个值(此处,仅为
i
中的一列)


要分配列,请使用
j
参数,如
colname:=expression
。有关详细信息,请参阅。

OMG,这非常有效!。谢谢你,弗兰克-你真的救了我的命!这绝对是我藏在我个人图书馆里的一个把戏。