Как вычислить в двоичной матрице в 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