Побитовое И или аналогичная операция над строками фрейма данных в R? - PullRequest
2 голосов
/ 03 декабря 2011

У меня есть два фрейма данных A и B, оба одинакового размера. Не гарантируется одинаковое расположение меток строк и столбцов между кадрами.

Оба кадра содержат значения 0 и 1, причем 1 указывает на наличие направленного «ребра» между строкой и столбцом кадра (и, соответственно, 0 указывает на отсутствие соединения).

Я бы хотел найти "ребра", общие для обоих кадров. Другими словами, мне нужен фрейм данных тех же измерений, что и A и B, которые содержат 1 значения, в которых есть 1 в строке и столбце обоих A и B.

В настоящее время я перебираю строки и столбцы и проверяю, оба ли они 1.

Это работает, но я думаю, что есть более эффективный способ сделать это. Есть ли способ сделать эквивалент операции «побитовое И» над векторами строк фреймов данных, которая возвращает вектор строк, который я могу вставить обратно в новый фрейм данных? Или есть другой, более разумный (и эффективный) подход?

EDIT

Матричное умножение происходит намного быстрее, чем мой первоначальный подход. Сортировка была ключом к созданию этой работы.

findCommonEdges <- function(edgesList) {
    edgesCount <- length(edgesList)
    print("finding common edges...")
    for (edgesIdx in 1:edgesCount) {
        print(paste("...searching against frame", edgesIdx, sep=" "))
        edges <- edgesList[[edgesIdx]]
        if (edgesIdx == 1) {
            # define commonEdges data frame as copy of first frame
            commonEdges <- edges
            next
        }
        #
        # we reorder edge data frame row and column labels 
        # to do matrix multiplication and find common edges
        #
        edges <- edges[order(rownames(commonEdges)), order(colnames(commonEdges))]
        commonEdges <- commonEdges * edges
    }
    commonEdges
}

Ответы [ 2 ]

4 голосов
/ 03 декабря 2011

Вы можете использовать обычное умножение для этого!: -)

// generate data
a = matrix(rbinom(100, 1, 0.5), nrow = 10)
b = matrix(rbinom(100, 1, 0.5), nrow = 10)

a * b // this is the result!

Вы также можете использовать логический оператор &, который является "побитовым и", который вы ищете.Ваше выражение будет выглядеть как (a & b) + 0 (+ 0 будет просто преобразовывать логическое значение обратно в целое).

Примечание: с кадрами данных оно работает точно так же.

0 голосов
/ 03 декабря 2011

Может быть, что-то подобное?

df1 <- as.data.frame(matrix(sample(0:1,25,replace = TRUE),5,5))
df2 <- as.data.frame(matrix(sample(0:1,25,replace = TRUE),5,5))
df3 <- matrix(0,5,5)
df3[df1 == 1 & df2 == 1] <- 1
> df3
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    0    0
[2,]    0    0    0    1    1
[3,]    1    1    1    0    0
[4,]    0    1    0    0    0
[5,]    0    0    0    0    0

Я получил матрицу, но при необходимости вы можете снова преобразовать ее обратно во фрейм данных.Но если вы просто имеете дело с данными 0/1, нет никакой реальной причины не использовать матрицы.(Опять же, я не знаю много деталей о вашей конкретной ситуации ...)

...