2014-10-12 2 views
4

Я использую следующий код для генерации случайной матрицы с некоторыми элементами = 1 вблизи диагонали, остальное = 0. (Это в основном случайное блуждание вдоль главная диагональ)R: Заменить «недиагональные» элементы случайной матрицы

n <- 20 
rw <- matrix(0, ncol = 2, nrow = n) 
indx <- cbind(seq(n), sample(c(1, 2), n, TRUE)) 
rw[indx] <- 1 
rw[,1] <- cumsum(rw[, 1])+1 
rw[,2] <- cumsum(rw[, 2])+1 
rw2 <- subset(rw, (rw[,1] <= 10 & rw[,2] <= 10)) 
field <- matrix(0, ncol = 10, nrow = 10) 
field[rw2] <- 1 
field 

    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 1 1 1 0 0 0 0 0  0 
[2,] 0 0 0 1 0 0 0 0 0  0 
[3,] 0 0 0 1 0 0 0 0 0  0 
[4,] 0 0 0 1 1 1 1 0 0  0 
[5,] 0 0 0 0 0 0 1 1 0  0 
[6,] 0 0 0 0 0 0 0 1 0  0 
[7,] 0 0 0 0 0 0 0 1 0  0 
[8,] 0 0 0 0 0 0 0 1 1  1 
[9,] 0 0 0 0 0 0 0 0 0  0 
[10,] 0 0 0 0 0 0 0 0 0  0 

Следующей вещь, я хотел бы заменить 0 элементов в правой/верхней сторону 1-элементов на 1. для приведенных выше матриц желаемого результата будет:.

 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 1 1 1 1 1 1 1 1  1 
[2,] 0 0 0 1 1 1 1 1 1  1 
[3,] 0 0 0 1 1 1 1 1 1  1 
[4,] 0 0 0 1 1 1 1 1 1  1 
[5,] 0 0 0 0 0 0 1 1 1  1 
[6,] 0 0 0 0 0 0 0 1 1  1 
[7,] 0 0 0 0 0 0 0 1 1  1 
[8,] 0 0 0 0 0 0 0 1 1  1 
[9,] 0 0 0 0 0 0 0 0 0  0 
[10,] 0 0 0 0 0 0 0 0 0  0 

Я попытался

fill <- function(row) {first = match(1, row); if (is.na(first)) {row = rep(1, 10)} else {row[first:10] = 1}; return(row)} 
field2 <- apply(field, 1, fill) 
field2 

Но это дает мне вместо этого:

 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 0 0 0 0 0 0 0 1  1 
[2,] 1 0 0 0 0 0 0 0 1  1 
[3,] 1 0 0 0 0 0 0 0 1  1 
[4,] 1 1 1 1 0 0 0 0 1  1 
[5,] 1 1 1 1 0 0 0 0 1  1 
[6,] 1 1 1 1 0 0 0 0 1  1 
[7,] 1 1 1 1 1 0 0 0 1  1 
[8,] 1 1 1 1 1 1 1 1 1  1 
[9,] 1 1 1 1 1 1 1 1 1  1 
[10,] 1 1 1 1 1 1 1 1 1  1 

Может кто-нибудь помочь мне исправить это?

Приветствия,

MCE

PS: Если первая строка является все нули (как это может произойти с указанным кодом) он должен быть изменен на всех из них.

+1

ли '' upper.tri' и lower.tri' приходят удобно? –

+1

Почему вы не переносите поле2? – jimifiki

+0

@ Roman Luštrik: Не совсем, потому что они не являются истинно диагональными элементами, просто где-то рядом с главной диагональю. – mce

ответ

0

Это должно работать:

MaxFull <- which.max((apply(field,1,sum) > 0) * (1:10)) 
rbind(t(apply(field[1:MaxFull,], 1, fill)),matrix(0,ncol=10,nrow=10-MaxFull)) 

заметил, что он использует заполнить, как вы определили его.

+0

Вы правы! Вам нужно провести различие между строками нулей в верхней или нижней части матрицы! Ваш код выполняет эту работу! Большое спасибо, mce – mce

0

В help для значения apply: «Если каждый вызов FUN возвращает вектор длины n, тогда apply возвращает массив размерности c (n, dim (X) [MARGIN])». Итак, вы хотите перенести это. Операции печати были добавлены в функцию заполнения, чтобы подтвердить операцию. Вы можете проверить, скрывает ли ваша функция другую функцию, есть функция с именем fill, но в данном случае это не имеет значения.

n <- 20 
rw <- matrix(0, ncol = 2, nrow = n) 
indx <- cbind(seq(n), sample(c(1, 2), n, TRUE)) 
rw[indx] <- 1 
rw[,1] <- cumsum(rw[, 1])+1 
rw[,2] <- cumsum(rw[, 2])+1 
rw2 <- subset(rw, (rw[,1] <= 10 & rw[,2] <= 10)) 
field <- matrix(0, ncol = 10, nrow = 10) 
field[rw2] <- 1 
field 
myfill <- function(row) { 
    print("Function start") 
    print(row) 
    first = match(1, row) 
    print(paste("Match", first)) 
    if (is.na(first)) { 
    row = rep(1, 10) 
    } else { 
    row[first:10] = 1 
    }; 
    print(row) 
    flush.console() 
    return(row) 
} 
field2 = t(apply(field, 1, myfill)) 
field2 
+0

работает прекрасным, спасибо большое !!! – mce

2

Почему не просто:

t(apply(field,1,cummax)) 

Один экземпляр:

dput(field) 
structure(c(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0), .Dim = c(10L, 
10L)) 

> field 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 0 0 0 0 0 0 0 0  0 
[2,] 1 1 1 1 1 1 0 0 0  0 
[3,] 0 0 0 0 0 1 0 0 0  0 
[4,] 0 0 0 0 0 1 0 0 0  0 
[5,] 0 0 0 0 0 1 1 1 1  1 
[6,] 0 0 0 0 0 0 0 0 0  0 
[7,] 0 0 0 0 0 0 0 0 0  0 
[8,] 0 0 0 0 0 0 0 0 0  0 
[9,] 0 0 0 0 0 0 0 0 0  0 
[10,] 0 0 0 0 0 0 0 0 0  0 

Выход:

> t(apply(field,1,cummax)) 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 0 0 0 0 0 0 0 0  0 
[2,] 1 1 1 1 1 1 1 1 1  1 
[3,] 0 0 0 0 0 1 1 1 1  1 
[4,] 0 0 0 0 0 1 1 1 1  1 
[5,] 0 0 0 0 0 1 1 1 1  1 
[6,] 0 0 0 0 0 0 0 0 0  0 
[7,] 0 0 0 0 0 0 0 0 0  0 
[8,] 0 0 0 0 0 0 0 0 0  0 
[9,] 0 0 0 0 0 0 0 0 0  0 
[10,] 0 0 0 0 0 0 0 0 0  0 
+0

+1 это должно быть +10 –

+0

True R элегантность! Спасибо! –

+0

+1 приятное использование cummax. В любом случае первая строка вывода неверна. – jimifiki

Смежные вопросы