我有100,000个5长度向量(下面的列表VECTORS),其元素是从一百万个值中选择的。
# dictionary
dictionary=seq(1:1e6)
# generate 100,000 5-length vectors whose elements are chosen from dictionary
VECTORS <- lapply(c(1:1e5), sample, x = dictionary, size =5)
我的问题是将每个完全相同的向量映射到一个整数,即我需要一个输入向量并产生整数的mappy函数。
例如mappy(c(58431, 976854, 661294, 460685, 341123))=15
。你知道如何以有效的方式做到这一点吗?
附属问题:如果我的载体长度不再相同怎么办?
答案 0 :(得分:6)
我假设你想在列表中的向量和整数之间进行双射。一种方法是从向量的字符表示中创建一个因子变量。让我们从您的代码的可重现版本开始(我将它变成一个较小的向量):
set.seed(144)
VECTORS <- replicate(1e2, sample(seq_len(1e6), 5), FALSE)
现在您可以从每个向量的字符表示创建一个因子变量:
fvar <- factor(sapply(VECTORS, paste, collapse=" "))
现在我们在VECTORS
和整数的元素的字符串表示之间有一个双射:
vec <- c(894025, 153892, 98596, 218401, 36616) # 15th element of VECTORS
which(levels(fvar) == paste(vec, collapse=" "))
# [1] 90
levels(fvar)[90]
# [1] "894025 153892 98596 218401 36616"
as.numeric(strsplit(levels(fvar)[90], " ")[[1]])
# [1] 894025 153892 98596 218401 36616
如果你想把它们包装成很好的功能:
id.from.vec <- function(vec) which(levels(fvar) == paste(vec, collapse=" "))
id.from.vec(c(894025, 153892, 98596, 218401, 36616))
# [1] 90
vec.from.id <- function(id) as.numeric(strsplit(levels(fvar)[id], " ")[[1]])
vec.from.id(90)
# [1] 894025 153892 98596 218401 36616
请注意,即使向量长度不同,这也可以开箱即用。
答案 1 :(得分:6)
键控data.table具有很好的查找属性:
library(data.table)
set.seed(1)
VECTORS <- lapply(seq(1e5), sample, x = 1e6, size = 5)
VECmap <- setkey(rbindlist(lapply(unique(VECTORS), as.list)))[, ID := .I]
# V1 V2 V3 V4 V5 ID
# 1: 13 897309 366563 678873 6571 1
# 2: 15 557977 640484 732531 848939 2
# 3: 48 18120 911805 188728 805726 3
# 4: 48 830301 862433 506297 877432 4
# 5: 52 873436 824165 86251 576173 5
# ---
# 99996: 999911 583599 803402 240910 931996 99996
# 99997: 999931 146505 287431 180259 230904 99997
# 99998: 999937 175888 266336 874987 982951 99998
# 99999: 999950 960139 455084 586956 875504 99999
# 100000: 999993 191750 258982 518519 78087 100000
mapVEC <- function(...) VECmap[.(...)]$ID
mapID <- function(id) unlist(VECmap[ID==id,!"ID",with=FALSE], use.names=FALSE)
# example usage
mapVEC(52, 873436, 824165, 86251, 576173)
# 5
mapID(5)
# 52 873436 824165 86251 576173
评论正如@Roland所提到的,(a)1..1e6和(b)所有所有 5个不同数字的长度序列(1)之间的双射。 1e5是不可能的,所以我只是猜测这是OP所追求的。
当您使用...
作为参数编写函数时,这意味着接受任意数量的未命名参数。在函数中,这些参数可以用...
引用,但通常也可以在c(...)
和list(...)
中看到。在data.table中,.(...)
是list(...)
的别名。要查看编写函数的文档,请键入help.start()
并单击“&#34; R语言定义”。&#34;