#r #list #indicator
#r #Список #индикатор
Вопрос:
У меня есть list
содержащие последовательности чисел. Я хочу создать a list
, который указывает все ненулевые элементы вплоть до первого элемента, который соответствует определенному пределу. Я также хочу создать a list
, который указывает все ненулевые элементы после первого элемента, чтобы соответствовать определенному пределу.
Я предпочитаю базовое R
решение. Предположительно, решение будет использоваться lapply
, но я не смог придумать простое решение.
Ниже приведен минимально воспроизводимый пример, в котором предел равен 2:
my.limit <- 2
my.samples <- list(0,c(1,2),0,c(0,1,1),0,0,0,0,0,c(1,1,2,2,3,4),c(0,1,2),0,c(0,0,1,1,2,2,3))
Вот два желаемых lists
:
within.limit <- list(0,c(1,1),0,c(0,1,1),0,0,0,0,0,c(1,1,1,0,0,0),c(0,1,1),0,c(0,0,1,1,1,0,0))
outside.limit <- list(0,c(0,0),0,c(0,0,0),0,0,0,0,0,c(0,0,0,1,1,1),c(0,0,0),0,c(0,0,0,0,0,1,1))
Комментарии:
1. Каждая последовательность сортируется в порядке возрастания?
2. Да, каждая последовательность сортируется в порядке возрастания.
Ответ №1:
Мы можем использовать match
с nomatch
аргументом как очень большое число (должно быть больше любой длины списка, по какой-то причине я не смог использовать Inf
здесь.)
within.limit1 <- lapply(my.samples, function(x)
(x > 0 amp; seq_along(x) <= match(my.limit, x, nomatch = 1000)))
outside.limit1 <- lapply(my.samples, function(x)
(seq_along(x) > match(my.limit, x, nomatch = 1000)))
Проверка правильности вывода отображаемого :
all(mapply(function(x, y) all(x == y), within.limit, within.limit1))
#[1] TRUE
all(mapply(function(x, y) all(x == y), outside.limit, outside.limit1))
#[1] TRUE
Комментарии:
1. Очень хороший ответ. Не могли бы вы объяснить знак ?
2.
Знак преобразует логические значения в целые числа. Посмотрите на вывод
c(TRUE, FALSE, TRUE)
Ответ №2:
Я бы сделал
within.limit <- lapply(my.samples, function(x)
(x!=0 amp; (x<limit | cumsum(x == limit)==1)))
outside.limit <- lapply(my.samples, function(x)
(x!=0 amp; (x>limit | cumsum(x == limit)>1)))
Ответ №3:
foo <- function(samples, limit, within = TRUE) {
`%cp%` <- if (within) `<=` else `>`
lapply(samples, function(x) pmin(x, seq_along(x) %cp% match(my.limit, x, nomatch = 1e8)))
}
> all.equal(foo(my.samples, my.limit, FALSE), outside.limit)
# [1] TRUE
> all.equal(foo(my.samples, my.limit, TRUE), within.limit)
# [1] TRUE
Ответ №4:
Мы можем использовать findInterval
lapply(my.samples, function(x)
(x > 0 amp; seq_along(x) <= findInterval(my.limit, x)-1))
и
lapply(my.samples, function(x) (seq_along(x) > findInterval(my.limit, x)-1))