2015-10-11 1 views
2

У меня есть 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, например. Знаете ли вы, как это сделать эффективно?

Вспомогательный вопрос: что, если мои векторы не имеют такой же длины?

+4

Недостаточно целых чисел для отображения '1e6^5' возможных векторов. – Roland

+1

Похоже, что тоже, что-то вроде 'match (VECTORS, unique (VECTORS)), может быть, может быть полезно –

ответ

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 

Обратите внимание, что это работает из коробки, даже если векторы различной длины.

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, взаимно однозначное соответствие между (а) 1..1e6 и (б) всех 5-длина последовательности различных чисел из 1..1e5 невозможны, поэтому я просто догадываюсь, что это то, что происходит после OP.

Когда вы пишете функцию с ... в качестве аргумента, это означает, что принято произвольное количество неназванных аргументов. Внутри функции эти аргументы можно отнести к ..., но часто также видны с c(...) и list(...). В таблице данных. .(...) является псевдонимом для list(...). Чтобы просмотреть документацию для функций записи, введите help.start() и нажмите «Определение языка R».