эффективно найти первый ненулевой элемент (соответствующий столбец) таблицы данных - PullRequest
2 голосов
/ 22 апреля 2019

В стеке есть несколько ответов на приведенный ниже тип вопроса, но все они неэффективны и плохо масштабируются.

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

    tempmat=matrix(c(1,1,0,4,1,0,0,4,0,1,0,4, 0,1,1,4, 0,1,0,5),5,4,byrow=T)
    tempmat=rbind(rep(0,4),tempmat)
    tempmat=data.table(tempmat)
    names(tempmat)=paste0('prod1vint',1:4)

Вот как выглядят данные, хотя они НАМНОГО больше, поэтому решение не может быть подходом, основанным на применении или построчном подходе.

> tempmat
   prod1vint1 prod1vint2 prod1vint3 prod1vint4
1:          0          0          0          0
2:          1          1          0          4
3:          1          0          0          4
4:          0          1          0          4
5:          0          1          1          4
6:          0          1          0          5

Я хочу идентифицировать столбец первого ненулевого элемента, поэтому вывод будет выглядеть следующим образом:

> tempmat
   prod1vint1 prod1vint2 prod1vint3 prod1vint4 firstnonzero
1:          0          0          0          0           NA
2:          1          1          0          4            1
3:          1          0          0          4            1
4:          0          1          0          4            2
5:          0          1          1          4            2
6:          0          1          0          5            2

1 Ответ

2 голосов
/ 22 апреля 2019

Один из вариантов - использовать rowSums с max.col, указав ties.method = "first"

temp <- tempmat != 0
(NA^(rowSums(temp) == 0)) * max.col(temp, ties.method = "first")
#[1] NA  1  1  2  2  2

max.col, чтобы получить индекс столбца первого максимального значения в каждой строке.Однако это вернет 1 в случае, если все значения равны 0 (как в 1-й строке), поскольку 0 является максимальным значением в строке.Чтобы избежать этого, мы проверяем, есть ли хотя бы одно ненулевое значение в строке, используя rowSums и умножаем его на max.col output.

...