Как написать условие на минимальных элементах?

#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) все элементы, значение которых ниже значения в diagnoal 0 должно быть -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