Получить индекс первого TRUE-элемента каждого столбца матрицы, но индекс должен быть от> до n - PullRequest
0 голосов
/ 14 января 2019

Итак, у меня есть матрица логических векторов, подобная этой:

r=10
c=10
m1 <- matrix(runif(r*c)>0.5, r, c)
> m1
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE
 [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
 [3,]  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
 [4,] FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE
 [5,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE
 [6,]  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE
 [7,] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
 [8,] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
 [9,]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[10,]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE

И такой вектор:

v1 <- round(runif(10,1,10))
> v1
 [1] 6 5 7 5 5 4 4 2 1 10

Как я могу получить 10 индексов> v1 первого ИСТИННОГО значения каждого столбца m1?

Итак, для этого примера я хочу получить этот вектор:

[1] 9 7 8 NA 6 5 7 3 3 NA

Спасибо за вашу помощь

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Это то, что вы хотите?

r=10
c=10
set.seed(42)
m1 <- matrix(runif(r*c)>0.5, r, c)
set.seed(314)
v1 <- round(runif(10,1,10))

out = sapply(1:10, function(i) 
{ 
  v = v1[i]
  r = m1[v:10,i]
  j = which(r)[1] + v - 1
})

out

Мой ввод (воспроизводимый с семенем)

> m1
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE
 [2,]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
 [3,] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [4,]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [5,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
 [6,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
 [7,]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
 [8,] FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE
 [9,]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE
[10,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE

> v1
 [1] 2 3 8 3 3 4 3 4 6 8

Мой вывод

> out
 [1]  4  6 10  4  4  6  4  6 NA  9
0 голосов
/ 14 января 2019

Получите индексы строки / столбца для каждого TRUE, используя which. Код внутри which использует комбинацию sweep для вычисления, является ли это большее число строк, и исходного объекта TRUE / FALSE mat. Затем эти индексы устанавливаются на первое совпадение в каждом столбце с использованием match, который возвращает NA, если в столбце нет значения.

# using Maurits' data

matsel <- which(sweep(row(mat), 2, v1, FUN=`>`) & mat, arr.ind=TRUE)
matsel[,"row"][match(seq_len(ncol(mat)), matsel[,"col"])]
#[1] NA NA  3  5  8  2  9  8  2  2

Это также должно очень хорошо масштабироваться, поскольку позволяет избежать зацикливания столбцов или строк. Единственное, на что стоит обратить внимание, - это то, что matsel станет большим и захлебнется вашей памятью, поскольку она хранит местоположение каждого значения TRUE.

0 голосов
/ 14 января 2019

Один из вариантов - использовать mapply. Вот воспроизводимый пример с использованием фиксированного случайного начального числа.

set.seed(2017)
r <- 10
c <- 10
m1 <- matrix(runif(r*c) > 0.5, r, c)    
v1 <- round(runif(10,1,10))   

mapply(function(x, y) { idx <- which(x == TRUE); idx[idx > y][1]}, as.data.frame(m1), v1, USE.NAMES = F)
#[1] NA NA  3  5  8  2  9  8  2  2

Объяснение: Для каждого столбца m1 мы извлекаем индексы TRUE записей в idx; затем мы возвращаем первый индекс idx, который больше, чем запись с номером столбца в v1; если такого числа не существует, оно автоматически возвращает NA.

Примечание. Чтобы mapply одновременно зацикливался на столбцах m1 и записях v1, нам необходимо преобразовать m1 в data.frame.


Пример данных

При вышеуказанном фиксированном случайном семени выборка данных составляет

m1
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
# [1,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE
# [2,]  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
# [3,] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
# [4,] FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
# [5,]  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
# [6,]  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
# [8,] FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE
# [9,] FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE
#[10,] FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE

v1
#[1]  9 10  2  3  6  1  5  6  1  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...