Есть ли более быстрый способ применения логических операций для подмножества большого набора данных в R?

Первый пост на Stackru, так что будьте осторожны, если я не совсем правильно понял этикет.

У меня есть большой фрейм данных (ну, на самом деле, семь из них, но это не важно), содержащий руки, взятые из колоды карт. У меня есть еще один массив, показывающий, какие карты из начальной руки игрок решил оставить. Любые карты, которые не были удержаны, перетягиваются из колоды. В первом фрейме данных хранятся все извлеченные карты, поэтому каждая строка может иметь длину от 5 до 10 столбцов, для карт от 5 до 0. Имеет ли это смысл? Например:

> str(cards01)
'data.frame':   5044033 obs. of  10 variables

> head(cards01)
   V1  V2  V3  V4  V5  V6  V7 V8  structure(c("", "", "", "", "", ""), class = "AsIs")
1  D0 D10  H0  C5  H1  S3  C4 D6                                                      
2  D5 S10  H7  C7  S0  S5 S12 H5                                                      
3  S4  H4  C1  D4 D11  H6  D1                                                         
4  C3  C9  D9 S10  S2  C7  S3 D2                                                      
5 H11  C0  C6  H3 H12 C11  S0                                                         
6 C10  C9 D11  D8  D5  S8

> str(heldCards01)
 num [1:5044033, 1:5] 1 3 1 2 1 1 2 1 1 1 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ ..$ : chr [1:5] "1" "2" "3" "4" ...

> head(heldCards01)
     1 2  3  4  5
[1,] 1 3 NA NA NA
[2,] 3 4 NA NA NA
[3,] 1 2  4 NA NA
[4,] 2 3 NA NA NA
[5,] 1 4  5 NA NA
[6,] 1 2  3  4 NA

Итак, что я делаю, это создаю новый фрейм данных, который просто содержит карты, которыми заканчивает игрок, то есть удаляет ячейки для каждой строки, которые не идентифицированы в массиве удерживаемых карт. Я написал код для этого, но теперь он работает все выходные и до сих пор не закончен. Это код, который я запускаю (все это происходит через лабиринт, чтобы пройти через каждую из имеющихся у меня пар данных / матрицы, бит, который я пытаюсь оптимизировать, происходит в mclapply):

all.hands <- lapply(stakes, function(stake){
  cardsOb <- get(paste("cards", stake, sep = ""))
  heldOb <- get(paste("heldCards", stake, sep = ""))
  l <- length(cardsOb[,1])
  mclapply(1:l, function(rowNum) {
    row <- (heldOb[rowNum,])
    theNAs <- as.logical(is.na(row))
    heldIndex <- row[!theNAs]
    discarded <- c(1,2,3,4,5)[-heldIndex]
    if(length(discarded) >= 1) {
      hand <- cardsOb[rowNum,-discarded]
    } else {
      hand <- cardsOb[rowNum,]
    }
    hand <- sort(hand)
  })
})

Есть ли какие-то функции, которые мне не хватает, которые могут вырезать некоторые шаги? Было бы быстрее, если бы фрейм данных был массивом? Должен ли я ждать дни и дни? Я работаю на Z620 с двумя четырехъядерными процессорами Xeon E5-2407 и 32 ГБ памяти, если это имеет значение.

1 ответ

Вот как я это сделаю. для простоты я предполагаю, что ваше первоначальное хранение карты находится в кадре данных df1, а индексы хранения карты - в df2 (только измененные имена)

Идея состоит в том, чтобы использовать строки df2 в качестве индексов для сопоставления строк df1 и повторять их для всех строк. Чтобы избежать проблем с классами, я работаю с массивами, а не с data.frames (которые не очень хорошие индексы)

Это можно сделать одной командой "geekish":

holdings = t(sapply(1:nrow(df1),function(x) as.matrix(df1)[x,][as.matrix(df2)[x,]]))

Затем вы можете изменить имена строк и столбцов, создать новый data.frame и т. Д.

Есть, вероятно, более хорошие способы сделать это, но я думаю, что вышеупомянутое довольно просто Не стесняйтесь спрашивать, не понимаете ли вы что-то в этой команде

Другие вопросы по тегам