2015-07-17 3 views
1

Итак, я знаю, чтобы определить первое вхождение определенного элемента в каждой строке, в которой вы используете функцию apply с помощью which.max или which.min. Вот код, который я использую прямо сейчас.What.max произвел тот же результат

x <- matrix(c(20,9,4,16,6,2,14,3,1),nrow=3) 
x 
apply(3 >= x,1,which.max) 

Это производит и выход:

[1] 1 3 2 

Теперь, когда я пытаюсь сделать то же самое на другой матрице "x2"

x2 <- matrix(c(3,9,4,16,6,2,14,3,1),nrow=3) 
x2 
apply(3 >= x2,1,which.max) 

Выход есть то же самое;

[1] 1 3 2 

Но для «x2» это правильно, потому что первая строка Матрица «x2» действительно есть значение меньше или равно трем.

Теперь мой вопрос, который, вероятно, является чем-то простым, - это то, почему функции apply производят одно и то же для «x» и «x2». Для «х» ниже я хочу что-то вроде:

[1] 0 3 2 

Или, может быть, даже что-то вроде этого:

[1] NA 3 2 

Я видел вопросы на переполнение стека, прежде чем на which.max не продуцирующих НСБУ и ответ должен был просто использовать функцию(), но поскольку я использую матрицу, и я хочу, чтобы первое появление у меня не было такой роскоши ... Я думаю.

+0

'который.max', примененный к логическому вектору, возвращает индекс первого ИСТИНА; или 1, если нет ИСТИННЫХ значений; или ничего не существует, только значения NA, как описано в документах. Не уверен, что ты здесь. – Frank

+0

@akrun это именно то, что я искал. Вы не возражаете, объясняя, что ";" делать в R-функциях? –

+0

Я думаю, что я ошибаюсь. Может быть «x [x> 3] <- -999; max.col (x) * !! rowSums (x> 0) ' – akrun

ответ

1

Мы можем заменить значения в 'x', которые являются> 3, с очень маленьким числом, например. -999 или значение, меньшее, чем минимальное значение в наборе данных. Получите индекс замененного вектора which.max и умножьте его на логический индекс, чтобы позаботиться о случаях, когда есть только отрицательные значения. то есть в случае «x» первая строка больше 3. Таким образом, заменяя -999, which.max возвращает 1 в качестве индекса, но мы предпочитаем иметь его NA или 0. Используя sum(x1>0, первая строка будет «0» и отрицает (!), она преобразуется в TRUE, снова отменяет и возвращает FALSE. Умножение кодера логического индекса на двоичный (0/1), и мы получаем значение «0» для первого случая.

apply(x, 1, function(x) {x1 <- ifelse(x>3, -999, x) 
        which.max(x1)*(!!sum(x1>0))}) 
    #[1] 0 3 2 

    apply(x2, 1, function(x) {x1 <- ifelse(x>3, -999, x) 
         which.max(x1)*(!!sum(x1>0))}) 
    #[1] 1 3 2 

Другой вариант заключается в использовании max.col

x1 <- replace(x, which(x>3), -999) 
max.col(x1)*!!rowSums(x1>0) 
#[1] 0 3 2 

x2N <- replace(x2, which(x2>3), -999) 
max.col(x2N)*!!rowSums(x2N>0) 
#[1] 1 3 2 

Или небольшая модификация будет

indx <- x*(x <=3) 
max.col(indx)*!!rowSums(indx) 
#[1] 0 3 2 
+1

Благодарим за помощь. Что это !! используется для в R –

+0

@AdamWarner Если вы посмотрите на 'rowSums (indx)', первое значение равно '0', т.е. все значение в этой строке больше 3. Нам нужно создать логический TRUE/FALSE или двоичный вектор вместо '0 3 3'. Один из способов - свести на нет ('!'), Так что 0 станет TRUE и все остальные FALSE. Отрицание снова дает TRUE изменено на FALSE и наоборот. Это, когда мы умножаем, принуждается к двоичному '0/1' – akrun

+0

Woah классный, очень интересный. –

0

Поместите колонку перед '(3> = х)', что есть бесконечность, тогда и только тогда, когда все записи в соответствующей строке «х» больше 3, а в противном случае - NaN. Затем нанесите «which.max» построчно, и, наконец, вычесть 1, из-за дополнительной колонки:

x <- matrix(c(20,9,4,16,6,2,14,3,1),nrow=3) 
a <- (!apply(3>=x,1,max))*Inf 

apply(cbind(a,3>=x), 1, which.max) - 1 

Это дает «0,3,2» «which.max» применяется к расширенной матрице

> cbind(a,3>=x) 

     a  
[1,] Inf 0 0 0 
[2,] NaN 0 0 1 
[3,] NaN 0 1 1