在列表中创建指标变量

Create indicator variables within a list

我有一个 list 包含数字序列。我想创建一个 list 来指示所有非零元素,直到第一个与定义的限制匹配的元素。我还想创建一个 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))

我们可以使用 matchnomatch 参数作为一个非常大的数字(应该大于列表的任何长度,出于某种原因我不能在这里使用 Inf .)

within.limit1 <- lapply(my.samples, function(x) 
                 +(x > 0 & 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

我们可以使用findInterval

lapply(my.samples, function(x) 
          +(x > 0 & seq_along(x) <= findInterval(my.limit, x)-1))

lapply(my.samples, function(x)  +(seq_along(x) > findInterval(my.limit, x)-1))

我愿意

within.limit <- lapply(my.samples, function(x) 
                           +(x!=0 & (x<limit | cumsum(x == limit)==1)))
outside.limit <- lapply(my.samples, function(x) 
                           +(x!=0 & (x>limit | cumsum(x == limit)>1)))
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