Вы в конечном итоге делает правильную процедуру. Зачем? Во-первых, мы будем тянуть выделяющейся выписку из страницы справки:
Position(f, x, right = FALSE, nomatch = NA_integer_)
Find
и Position
по образцу Common Lisp находят, если и позиционно-если, соответственно. Если есть элемент, для которого функция предиката дает true, тогда возвращается первый или последний такой элемент или его позиция в зависимости от того, правильно ли установлено значение false (по умолчанию) или true. Если такого элемента нет, возвращается значение, указанное в nomatch. Текущая реализация не оптимизирована для производительности.
Так, Position()
собирается применить f()
ко всем элементам x
и когда результат f()
является TRUE
(непосредственно или через принуждение) Position()
возвращает индекс этого элемента (если ничего не заканчивает тем, что TRUE
то он возвращает значение, присвоенное nomatch
).
Вот фактический источник Position()
функция:
Position <- function (f, x, right=FALSE, nomatch=NA_integer_) {
ind <- seq_along(x)
if (right) ind <- rev(ind)
for (i in ind) {
if (f(x[[i]])) return(i)
}
nomatch
}
После источника вы можете prbly увидеть, что min()
становится называется на первый элемент списка и возвращает значение, которое min()
вектора в списке позиция 1, и это значение не равно нулю, поэтому он считает, что он сделал хорошую работу и возвращает индекс списка, в котором он был.
Если вы делали:
Position(min, Map(function(x) {x-3}, dat))
, то вы увидели бы результат быть:
## [1] 2
и, возможно, думал, что это работает, но это возвращает только, что с первого элемента из списка 3
и 3-3 == 0
и 0
принуждаются к FALSE
.
ПРИМЕЧАНИЕ: ls
- это также имя базовой функции, которая является прекрасной, так как R знает, что делать на основе контекста использования, но мне не нравится потенциально вызывать странные ошибки в дороге в вызовах функций, разбивая очень общее пространство имен элементов, поэтому я использовал dat
вместо ls
.
Идея Position()
больше что-то вроде:
eqls4 <- function(x) x==4
Position(eqls4, Map(function(x) {x^2}, dat))
который делает возвращение:
## [1] 2
Итак, что вы в конечном итоге делает был 100% правильно.
Следует также отметить, что purrr
пакета предоставляет альтернативные функциональные идиомы, что (ИМО), имеет тенденцию быть более читаемыми + есть способы обеспечения надлежащих типов поддерживаются и экспортирует %>%
так трубопроводы также легко доступны:
library(purrr)
map(dat, ~.^2) %>%
flatten_dbl() %>%
which.min()
Thx для обширного ответа. Но это сводится к тому, что я использую неправильный подход, потому что функция min применяется к каждому элементу списка моего списка, и это возвращает [[1]], если это не сработает, как в вашем примере. Таким образом, использование списка и т. Д. Является правильным подходом? –
правый. 'flatten_dbl()' является "purrr'" безопасной "версией' unlist' (т. е. всегда будет возвращать вектор «double's vs, возможно, вектор символов»). – hrbrmstr
Thx, мне было просто любопытно и на самом деле неправильно поняли сферу применения и функцию Position. Но, возможно, это помогает другим людям :) –