Найти самое последнее совпадение в массиве [R] - PullRequest
0 голосов
/ 10 сентября 2018

Представьте массив чисел с именем A. На каждом уровне A вы хотите найти самый последний элемент с соответствующим значением.Вы можете легко сделать это с помощью цикла for следующим образом:

A = c(1, 1, 2, 2, 1, 2, 2)

for(i in 1:length(A)){   
  if(i > 1 & sum(A[1:i-1] == A[i]) > 0){ 
    answer[i] = max(which(A[1:i-1] == A[i]))
  }else{
    answer[i] = NA
  }
}

Но я хочу векторизовать этот цикл for (потому что я буду применять этот принцип для очень большого набора данных).Я попытался использовать sapply:

answer = sapply(A, FUN = function(x){max(which(A == x))})

Как видите, мне нужен какой-то способ уменьшения массива до значений, которые идут до x.Любой совет?

Ответы [ 4 ]

0 голосов
/ 10 сентября 2018

Вы можете сделать:

sapply(seq_along(A)-1, function(x)ifelse(any(a<-A[x+1]==A[sequence(x)]),max(which(a)),NA))
[1] NA  1 NA  3  2  4  6
0 голосов
/ 10 сентября 2018

Вот подход с dplyr, который является более многословным, но мне легче грокать. Мы начнем с записи row_number, создадим группу для каждого встречаемого числа, затем запишем предыдущую соответствующую строку.

library(dplyr)
A2 <- A %>% 
  as_tibble() %>%
  mutate(row = row_number()) %>%
  group_by(value) %>%
  mutate(last_match = lag(row)) %>%
  ungroup()
0 голосов
/ 10 сентября 2018

Вот функция, которую я сделал (основываясь на ответе Ронака):

lastMatch = function(A){
  uniqueItems = unique(A)
  firstInstances = sapply(uniqueItems, function(x){min(which(A == x))}) #for NA
  notFirstInstances = setdiff(seq(A),firstInstances)
  lastMatch_notFirstInstances = sapply(notFirstInstances, function(x) max(which(A[1:(x-1)] == A[x])))
  X = array(0, dim = c(0, length(A)))
  X[firstInstances] = NA
  X[notFirstInstances] = lastMatch_notFirstInstances
  return(X)
}
0 голосов
/ 10 сентября 2018

Мы можем использовать seq_along для циклического перебора индекса каждого элемента, а затем установить его подмножество и получить индекс max, где значение в последний раз произошло.

c(NA, sapply(seq_along(A)[-1], function(x) max(which(A[1:(x-1)] == A[x]))))
#[1]   NA    1 -Inf    3    2    4    6

Мы можем изменить -Inf на NA при необходимости в этом формате

inds <- c(NA, sapply(seq_along(A)[-1], function(x) max(which(A[1:(x-1)] == A[x]))))
inds[is.infinite(inds)] <- NA
inds
#[1] NA  1 NA  3  2  4  6

Приведенный выше метод выдает предупреждение, для удаления которого мы можем выполнить дополнительную проверку length

c(NA, sapply(seq_along(A)[-1], function(x) {
  inds <- which(A[1:(x-1)] == A[x])
 if (length(inds) > 0)
   max(inds)
 else
   NA
}))

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