2014-09-07 5 views
2

я пытаюсь решить следующую задачу:Создание комбинации последовательностей

Рассмотрим 5 простых последовательностей: 0: 100, 100: 0, Rep (0101), Rep (50101), Rep (100101)

Мне нужны наборы из 3 числовых переменных, которые имеют выше последовательности во всех комбинациях. Так как существует 5 последовательностей и 3 переменных, могут быть 5 * 5 * 5 комбинаций, следовательно, общее количество 12625 (5 * 5 * 5 * 101) чисел в каждой переменной (101 для каждой последовательности).

Они могут быть сгруппированы в data.frame из 12625 строк и 4 столбцов. Первая колонка (V) будет просто иметь seq (1: 12625) (рябины могут использоваться на своем месте). Другие 3 столбца (A, B, C) будут иметь более 5 последовательностей в разных комбинациях. Например, первые 101 строки будут иметь 0: 100 во всех 3 A, B и C. Следующие 101 строки будут иметь 0: 100 в A и B и 100: 0 в C. И так далее ...

Я могу создавать последовательности как:

s = list() 
s[[1]] = 0:100 
s[[2]] = 100:0 
s[[3]] = rep(0,101) 
s[[4]] = rep(50,101) 
s[[5]] = rep(100,101) 

Но как продолжить дальше? Мне действительно не нужен кадр данных, но мне нужна функция, которая возвращает список, содержащий значения c (A, B, C) для числа (первого или V столбца), отправленного на него. Количество может, очевидно, варьироваться от 1 до 12625.

Как создать такую ​​функцию. Я предпочел бы векторное решение или один, применяя семейные функции для оптимизации скорости.

ответ

4

Вы просили векторизованного решение, так вот один, используя только data.table (по аналогии с методикой @SimonGs)

library(data.table) 
grd <- CJ(A = seq_len(5), B = seq_len(5), C = seq_len(5)) 
res <- grd[, lapply(.SD, function(x) unlist(s[x]))] 
res 
#   A B C 
#  1: 0 0 0 
#  2: 1 1 1 
#  3: 2 2 2 
#  4: 3 3 3 
#  5: 4 4 4 
# ---    
# 12621: 100 100 100 
# 12622: 100 100 100 
# 12623: 100 100 100 
# 12624: 100 100 100 
# 12625: 100 100 100 
2

Я придумал два решения. Я считаю, что это трудно сделать с apply и нравится, поскольку они, как правило, дают результат, который не так приятно обрабатывать (возможно, кто-то может «приручить» их лучше, чем я могу: D)

Первое решение использует отдельные вызовы lapply, второй использует цикл for и некоторые программы No-No's. Лично я предпочитаю второй, первый один быстрее, хотя ...

grd <- expand.grid(a=1:5,b=1:5,c=1:5) 

# apply-ish 
A <- lapply(grd[,1], function(z){ s[[z]] }) 
B <- lapply(grd[,2], function(z){ s[[z]] }) 
C <- lapply(grd[,3], function(z){ s[[z]] }) 
dfr <- data.frame(A=do.call(c,A), B=do.call(c,B), C=do.call(c,C)) 

# for-ish 
mat <- NULL 
for(i in 1:nrow(grd)){ 
cur <- grd[i,] 
tmp <- cbind(s[[cur[,1]]],s[[cur[,2]]],s[[cur[,3]]]) 
mat <- rbind(mat,tmp) 
} 

Выход обоих dfr и mat, кажется, что вы описали.

Cheers!

+0

Исправлено объяснение, спасибо за замечание. – SimonG

+0

В ваших ответах представлены многие методы. – rnso