2013-09-02 2 views
2

Привет и хороший вечер из германии :)expand.grid с существующими кусками

Я довольно новыми для R, но я действительно утра в моих пределах понимания.

В основном у меня есть n матриц, которые находятся в списке. Они выглядят так:

$edu 
    cue op split pred 
1 edu <  1 TRUE 
2 edu >  1 TRUE 
3 edu ==  1 TRUE 
4 edu <  2 TRUE 
5 edu >  2 TRUE 
6 edu ==  2 TRUE 
7 edu <  3 TRUE 
8 edu >  3 TRUE 
9 edu ==  3 TRUE 

$religion 
     cue op split pred 
1 religion ==  0 TRUE 
2 religion ==  1 TRUE 
3 religion ==  0 FALSE 
4 religion ==  1 FALSE 

$med_exp 
     cue op split pred 
1 med_exp ==  0 TRUE 
2 med_exp ==  1 TRUE 
3 med_exp ==  0 FALSE 
4 med_exp ==  1 FALSE 

Что мне нужно, что-то похожее на то, что делает «expand.grid()». Мне нужно, чтобы все элементы были смешаны во всех возможных перестановках (я уже проверил пакет combinat), но в исходном порядке столбцов (med_exp, например, не должен иметь «split» более 1 и только «==» как оператор!) ,

Я был бы контрпродуктивным, если бы у меня был один и тот же «cuetest» (одна строка в одном списке) более одного раза в таблице. Мне нужны данные предпочтительно в матрице, потому что я хочу использовать «parRapply». То, как таблица должна выглядеть как

cue op split pred  cue op split pred  cue op split pred 
    edu <  1 TRUE religion ==  0 TRUE med_exp ==  0 TRUE 
    edu <  1 TRUE religion ==  0 TRUE med_exp ==  1 TRUE 
    edu <  1 TRUE religion ==  0 TRUE med_exp ==  0 FALSE 
    edu <  1 TRUE religion ==  0 TRUE med_exp ==  1 FALSE 

    [..] 
    med_exp == 0 TRUE edu  <  1 TRUE religion ==  0 TRUE 

Проблема, expand.grid путает даже подстолбцы, и то только давая мне память-проблему и не надо.

Вот данные для эксперимента:

structure(list(edu = structure(list(cue = structure(c(1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L), .Label = "edu", class = "factor"), op = structure(c(1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("<", ">", "=="), class = "factor"), 
    split = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 
    1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), pred = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE)), .Names = c("cue", "op", "split", 
"pred"), out.attrs = structure(list(dim = c(1L, 3L, 4L, 2L), 
    dimnames = structure(list(Var1 = "Var1=edu", Var2 = c("Var2=<", 
    "Var2=>", "Var2==="), Var3 = c("Var3=1", "Var3=2", "Var3=3", 
    "Var3=4"), Var4 = c("Var4=TRUE", "Var4=FALSE")), .Names = c("Var1", 
    "Var2", "Var3", "Var4"))), .Names = c("dim", "dimnames")), class = "data.frame", row.names = c(NA, 
-24L)), edu_hus = structure(list(cue = structure(c(1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L), .Label = "edu_hus", class = "factor"), op = structure(c(1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("<", ">", "=="), class = "factor"), 
    split = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 
    1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), pred = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE)), .Names = c("cue", "op", "split", 
"pred"), out.attrs = structure(list(dim = c(1L, 3L, 4L, 2L), 
    dimnames = structure(list(Var1 = "Var1=edu_hus", Var2 = c("Var2=<", 
    "Var2=>", "Var2==="), Var3 = c("Var3=1", "Var3=2", "Var3=3", 
    "Var3=4"), Var4 = c("Var4=TRUE", "Var4=FALSE")), .Names = c("Var1", 
    "Var2", "Var3", "Var4"))), .Names = c("dim", "dimnames")), class = "data.frame", row.names = c(NA, 
-24L)), religion = structure(list(cue = structure(c(1L, 1L, 1L, 
1L), .Label = "religion", class = "factor"), op = structure(c(1L, 
1L, 1L, 1L), .Label = "==", class = "factor"), split = c(0L, 
1L, 0L, 1L), pred = c(TRUE, TRUE, FALSE, FALSE)), .Names = c("cue", 
"op", "split", "pred"), out.attrs = structure(list(dim = c(1L, 
1L, 2L, 2L), dimnames = structure(list(Var1 = "Var1=religion", 
    Var2 = "Var2===", Var3 = c("Var3=0", "Var3=1"), Var4 = c("Var4=TRUE", 
    "Var4=FALSE")), .Names = c("Var1", "Var2", "Var3", "Var4" 
))), .Names = c("dim", "dimnames")), class = "data.frame", row.names = c(NA, 
-4L))), .Names = c("edu", "edu_hus", "religion")) 

Спасибо большое, Марк

+0

так, что ваша проблема именно? – dzada

+0

Извините, если это было недостаточно ясно. Мне нужен был «expand.grid», который не разорвал вычисления, которые у меня уже были в кадре данных, но рекомбинирует все строки DF во всех элементах списка. См. Ответ от @Roland, который работает как шарм. – Marc

ответ

3

Обратите внимание, что данные, предоставленные dput не то же самое, как показано выше. Кроме того, элементами списка являются data.frames, а не матрицы. Первое имеет смысл, потому что у вас есть сочетание разных типов (факторы, целые числа, логические), а матрица может содержать только один тип. Таким образом, код, который я здесь привел, также возвращает data.frame. Вы всегда можете использовать as.matrix, но я рекомендую это для большинства целей.

#create combinations of row indices 
ind <- expand.grid(seq_len(nrow(dat[[3]])), 
        seq_len(nrow(dat[[2]])), 
        seq_len(nrow(dat[[1]]))) 

#use subsetting and cbind 
res <- cbind(dat[[1]][ind[,3],], 
       dat[[2]][ind[,2],], 
       dat[[3]][ind[,1],]) 

head(res) 

#  cue op split pred  cue op split pred  cue op split pred 
# 1 edu <  1 TRUE edu_hus <  1 TRUE religion ==  0 TRUE 
# 1.1 edu <  1 TRUE edu_hus <  1 TRUE religion ==  1 TRUE 
# 1.2 edu <  1 TRUE edu_hus <  1 TRUE religion ==  0 FALSE 
# 1.3 edu <  1 TRUE edu_hus <  1 TRUE religion ==  1 FALSE 
# 1.4 edu <  1 TRUE edu_hus >  1 TRUE religion ==  0 TRUE 
# 1.5 edu <  1 TRUE edu_hus >  1 TRUE religion ==  1 TRUE 

Если у вас есть несколько столбцов, вы можете использовать lapply и do.call обобщить подход:

sl <- lapply(dat, function(df) seq_len(nrow(df))) 
sl <- sl[rev(seq_along(sl))] 
ind <- do.call(expand.grid, sl) 
ind <- ind[,rev(seq_along(dat))] 

res <- do.call(cbind, lapply(seq_along(dat), function(i) dat[[i]][ind[,i],])) 
+0

Ничего себе! Это потрясающе и удивительно быстро! Большое спасибо за ваши объяснения. Я еще не получил весь ваш код, но я над этим работаю. Приветствия и спасибо! – Marc

Смежные вопросы