от 1:n для каждого элемента списка R

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

myList <- c(14, 35, 12, 54, 67, 8, 32, 3, 78)

minVec <- function(x){
# Return a list of all numbers from x which are less than any previous number in the list
  outList <- list(x[1])
  for(i in 2:length(x)){
    if(x[i] < min(x[1:i - 1])){
      outList <- c(outList, x[i])}
  }
  return(unlist(outList))
}

minVec(myList)

Но мне нужно сделать это много раз во многих списках, и я хочу использовать lapply, чтобы ускорить это. Проблема в том, что для каждого элемента n списка x мне нужно найти минимум подмножества x[1:n - 1]. Можно ли это сделать в lapply (или как-то иначе векторизовать)? Как сказать «для каждого элемента этого списка добавить элемент в новый список, если элемент меньше любого предыдущего значения в списке»?


person TomR    schedule 09.05.2014    source источник


Ответы (1)


Ты ищешь :

unique(cummin(myList))

РЕДАКТИРОВАТЬ некоторые пояснения:

min подмножества x[1:n - 1] для каждого n из списка является кумулятивным минимумом списка. Поскольку cummin является векторизованным, результат имеет тот же размер, что и входной список, поэтому нам нужно unique, чтобы удалить дубликаты.

Это же решение можно обобщить для:

  • кумулятивные максимумы: cummax
  • общая сумма: cumsum
  • совокупный продукт: cumprod
person agstudy    schedule 09.05.2014
comment
Боже, это действительно сокращает потраченное время! - person Rich Scriven; 10.05.2014
comment
Это действительно круто, спасибо. Есть ли более общее решение, если мне нужно применить функцию, отличную от min, max, sum и т. д.? - person TomR; 10.05.2014
comment
Это интересно, но я бы попросил вас добавить, если возможно, любую дополнительную информацию к вашему подходу. - person Paulo E. Cardoso; 10.05.2014
comment
Всего три части: myList, cummin(myList) и unique(cummin(myList)). - person Rich Scriven; 10.05.2014
comment
@TomR вы можете подключить произвольную функцию вместо min к: sapply(seq_along(x), function(i) min(x[1:i])), но это будет намного медленнее - person eddi; 10.05.2014
comment
Способ найти идеальную функцию. Я уверен, что в данном случае это лучший вариант, но если вы хотите сделать то же самое и с другими функциями, векторизованная альтернатива — unique(Reduce(function(x,y) min(x,y), myList, accumulate=T)) - person MrFlick; 10.05.2014