#r #matrix #min
Вопрос:
У меня есть симметричная матрица с нулевыми диагональными элементами:
set.seed(42)
m<-matrix(runif(25),5)
m[lower.tri(m)] = t(m)[lower.tri(m)]
diag(m)<-0
m
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0000000 0.5190959 0.4577418 0.9400145 0.9040314
[2,] 0.5190959 0.0000000 0.7191123 0.9782264 0.1387102
[3,] 0.4577418 0.7191123 0.0000000 0.1174874 0.9888917
[4,] 0.9400145 0.9782264 0.1174874 0.0000000 0.9466682
[5,] 0.9040314 0.1387102 0.9888917 0.9466682 0.0000000
Мне нужно поставить -1 для всех элементов ниже диагонали, за исключением минимального элемента в каждом столбце:
Ожидаемый результат -:
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0000000 -1.0000000 -1.0000000 -1.0000000 -1.0000000
[2,] -1.0000000 0.0000000 -1.0000000 -1.0000000 -1.0000000
[3,] 0.4577418 -1.0000000 0.0000000 -1.0000000 -1.0000000
[4,] -1.0000000 -1.0000000 0.1174874 0.0000000 -1.0000000
[5,] -1.0000000 0.1387102 -1.0000000 0.9466682 0.0000000
Моя попытка:
for (i in 2:ncol(m))
#if (m[,i] > 0)
x <- pmin(x, m[,i])
x
min = which(m == min(m), arr.ind = TRUE)
min
Вопрос. Как добавить условие на диагональные элементы?
Комментарии:
1. В вашем примере это где-то путаешь то, что вы ищете: (1) все элементы ожидать минимум в каждом столбце должно быть
-1
, или (2) все элементы, которые являются пространственно ниже диагонали должны быть-1
исключением минимального или (3) все элементы, значение которых ниже значения в diagnoal0
должно быть-1
, кроме минимума?2. почему в столбце 2
0.5190959
указано значение-1
ожидаемого результата?3. Я обновил выходные данные
Ответ №1:
Вы можете попробовать это…но я почти уверен, что есть более простой способ.
m_tmp <- m
m_tmp[upper.tri(m, diag = T)] <- NA
library(tidyverse)
m_tmp %>%
as.data.frame() %>%
rowid_to_column() %>%
pivot_longer(-1) %>%
group_by(name) %>%
mutate(val = sum(is.na(value))) %>%
mutate(value = ifelse(val == 5, -1, value)) %>%
mutate(value = ifelse(value == min(value, na.rm = T), value, -1)) %>%
select(-val) %>%
filter(!is.na(value)) %>%
pivot_wider(names_from = "name", values_from = "value", values_fill = -1) %>%
select(-1) %>%
as.matrix()
V1 V2 V3 V4 V5
[1,] 0.0000000 -1.0000000 -1.0000000 -1.0000000 -1
[2,] -1.0000000 0.0000000 -1.0000000 -1.0000000 -1
[3,] 0.4577418 -1.0000000 0.0000000 -1.0000000 -1
[4,] -1.0000000 -1.0000000 0.1174874 0.0000000 -1
[5,] -1.0000000 0.1387102 -1.0000000 0.9466682 0
Ответ №2:
Вы можете сделать:
m[!sweep(m, 2, apply(replace(m, upper.tri(m, diag = TRUE), Inf), 2, min), `==`)] <- -1
`diag<-`(m, 0)
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0000000 -1.0000000 -1.0000000 -1.0000000 -1
[2,] -1.0000000 0.0000000 -1.0000000 -1.0000000 -1
[3,] 0.4577418 -1.0000000 0.0000000 -1.0000000 -1
[4,] -1.0000000 -1.0000000 0.1174874 0.0000000 -1
[5,] -1.0000000 0.1387102 -1.0000000 0.9466682 0