【问题标题】:Create indicator variables within a list在列表中创建指标变量
【发布时间】:2020-10-14 08:06:51
【问题描述】:

我有一个包含数字序列的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))

【问题讨论】:

  • 每个序列是按升序排列的?
  • 是的,每个序列都是按升序排列的。

标签: r list indicator


【解决方案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

【讨论】:

  • 非常好的答案。你能解释一下+号吗?
  • + 符号将逻辑值转换为整数。查看+c(TRUE, FALSE, TRUE)的输出
【解决方案2】:

我愿意

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

【讨论】:

    【解决方案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 & seq_along(x) <= findInterval(my.limit, x)-1))
      

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

      【讨论】:

        猜你喜欢
        • 2016-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 1970-01-01
        • 2021-07-03
        • 2017-03-24
        • 1970-01-01
        相关资源
        最近更新 更多