Как вычислить в двоичной матрице в R

Вот моя проблема, я не мог решить все это.

Предположим, что у нас есть следующий код:

## A data frame named a    
a <- data.frame(A = c(0,0,1,1,1), B = c(1,0,1,0,0), C = c(0,0,1,1,0), D = c(0,0,1,1,0), E = c(0,1,1,0,1))
## 1st function calculates all the combinaisons of colnames of a and the output is a character vector named item2
items2 <- c()
countI <- 1 
while(countI <= ncol(a)){
        for(i in countI){
                countJ <- countI + 1
                while(countJ <= ncol(a)){
                        for(j in countJ){
                                items2 <- c(items2, paste(colnames(a[i]), colnames(a[j]), collapse = '', sep = ""))
                        }
                        countJ <- countJ + 1
                }
                countI <- countI + 1
        }
}

И вот мой код, который я пытаюсь решить (вывод представляет собой числовой вектор с именем count_1):

## 2nd function
colnames(a) <- NULL ## just for facilitating the calculation
count_1 <- numeric(ncol(a)*2)
countI <- 1
while(countI <= ncol(a)){
        for(i in countI){
                countJ <- countI + 1
                while(countJ <= ncol(a)){
                        for(j in countJ){
                                s <- a[, i]
                                p <- a[, j]
                                count_1[i*2] <- as.integer(s[i] == p[j] & s[i] == 1)
                        }
                        countJ <- countJ + 1
                }
                countI <- countI + 1
        }
}

Но когда я выполняю этот код в консоли RStudio, возвращается непредвиденный результат!:

 count_1
 [1] 0 0 0 0 0 1 0 1 0 0

Тем не менее, я ожидаю следующий результат:

count_1
[1] 1 2 2 2 1 1 1 1 2 1

Вы можете посетить следующий URL, где вы можете найти изображение в Dropbox для подробного объяснения. https://www.dropbox.com/s/5ylt8h8wx3zrvy7/IMAG1074.jpg?dl=0

Я попытаюсь объяснить немного больше, я разместил 1-ую функцию (код), чтобы показать вам, что я ищу, именно этот пример и все. То, что я пытаюсь получить от второй функции (кода) - это вычисление количества вхождений числа 1 (сначала мы ставим counter = 0) в каждой строке (в то время как каждая строка из двух столбцов (например, AB) должна равняться единице в обоих столбцах, чтобы сказать, что counter = counter + 1) мы продолжаем, комбинируя каждый столбец со всеми другими столбцами (с AC, AD, AE, BC, BD, BE, CD, CE, а затем с DE), комбинация n!/2!(n-2)!, это означает, например, если у меня есть следующий кадр данных:

а =

ABCDE
0 1 0 0 0

0 0 0 0 1

1 1 1 1 1

1 0 0 1 0

1 0 1 0 1

Затем число вхождений числа 1 для каждой строки путем объединения двух первых столбцов выглядит следующим образом: (Обратите внимание, что я поставил colnames(a) <- NULL просто чтобы облегчить работу и быть более понятным)

0 1 0 0 0

0 0 0 0 1

1 1 1 1 1

1 0 0 1 0

1 0 1 0 1

### Example 1: #####################################################

поэтому отсюда я поставил (для столбцов A и B (AB))

s <- a[, i]
## s is equal to
## [1] 0 0 1 1 1
p <- a[, j]
## p is equal to
## [1] 1 0 1 0 0

Тогда я буду искать вхождение числа 1 в обоих векторах, при условии, что оно должно быть одинаковым, т.е. a[, i] == 1 && a[, j] == 1 && a[, i] == a[, j] и для этого примера числовой вектор будет [1] 1

### Example 2: #####################################################

Отсюда я положил (для столбцов A и D (AD))

s <- a[, i]
## s is equal to
## [1] 0 0 1 1 1
p <- a[, j]
## p is equal to
## [1] 0 0 1 1 0

Тогда я буду искать вхождение числа 1 в обоих векторах, при условии, что оно должно быть одинаковым, т.е. a[, i] == 1 && a[, j] == 1 && a[, i] == a[, j] и для этого примера числовой вектор будет [1] 2

И так далее, у меня будет числовой вектор с именем count_1 равно:

[1] 1 2 2 2 1 1 1 1 2 1

в то время как каждый индекс count_1 является комбинацией каждого столбца другими (без имен фрейма данных)

AB AC AD AE BC BD BE CD CE DE

1 2 2 2 1 1 1 1 2 1

1 ответ

Решение

Непонятно, что вы после всего.

Что касается первого фрагмента кода, это некрасивое R-кодирование, включающее целый набор ненужных while/for петли.

Вы можете получить тот же результат items2 в одной строке.

items2 <- sort(toupper(unlist(sapply(1:4, function(i)
    sapply(5:(i+1), function(j)
        paste(letters[i], letters[j], sep = ""))))));
items2;
# [1] "AB" "AC" "AD" "AE" "BC" "BD" "BE" "CD" "CE" "DE"

Что касается второго фрагмента кода, пожалуйста, объясните, что вы пытаетесь вычислить. Вполне вероятно, что эти while/for петли так же не нужны, как в первом случае.


Обновить

Обратите внимание, что это основано на a как определено в начале вашего поста. Ваш ожидаемый результат основан на другом a, что ты изменил дальше вниз по посту.

Там нет необходимости в for/while цикл, обе "функции" могут быть записаны в двух однострочниках.

# Your sample dataframe a
a <- data.frame(A = c(0,0,1,1,1), B = c(1,0,1,0,0), C = c(0,0,1,1,0), D = c(0,0,1,1,0), E = c(0,1,1,0,1))

# Function 1
items2 <- toupper(unlist(sapply(1:(ncol(a) - 1), function(i) sapply(ncol(a):(i+1), function(j)
        paste(letters[i], letters[j], sep = "")))));
# Function 2
count_1 <- unlist(sapply(1:(ncol(a) - 1), function(i) sapply(ncol(a):(i+1), function(j)
        sum(a[, i] + a[, j] == 2))));

# Add names and sort
names(count_1) <- items2;
count_1 <- count_1[order(names(count_1))];
# Output
count_1;
#AB AC AD AE BC BD BE CD CE DE
# 1  2  2  2  1  1  1  2  1  1
Другие вопросы по тегам