Создание переменных индикатора в списке

#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))