【问题标题】:Testing equality for each element of two identically structured lists in R: how to be faster测试 R 中两个结构相同的列表的每个元素的相等性:如何更快
【发布时间】:2018-03-17 13:33:11
【问题描述】:

我的目标是得到一个与两个初始列表具有相同结构的列表,不同之处在于每个元素都必须是一个逻辑向量。

考虑两个列表:

mlist <- rep(list(rep(c(0,2,4),68),c(1),
              sample(x = c("a","b"),size = 1, prob = c(.5,.5))),200)
klist <- rep(list(rep(c(0,2,3),68), c(0),
              sample(x = c("a","b"),size = 1, prob = c(.5,.5))),200)

请注意,在给定列表中,每个元素都是一个向量,可以是字符串或数字,它们的长度不一定相同。但是,这两个列表具有完全相同的结构。

我正在寻找的列表具有相同的结构,并表示两个列表的每个向量中的每个元素的相等性。 For 循环提供了一个令人不快的解决方案:

hon <- as.list(rep(NA ,length(mlist)))
for(i in seq(length(mlist))){
  for (m in seq(length(mlist[[i]]))){
    hon[[i]][[m]] <- mlist[[i]][[m]]==klist[[i]][[m]]
  }
}

另一种解决方案,使用 purrr 包,稍微优雅一些​​,但速度较慢,是

han <- map2(klist,  mlist, map2_lgl, identical)

对于 for 循环方法,经过的时间是 0.054,对于 purr 方法是 0.129。有没有更有效的替代方案?

【问题讨论】:

    标签: r performance list purrr


    【解决方案1】:

    您是否总是将向量作为列表的元素?

    如果是这样,您可以使用矢量化的==。做吧

    hin <- lapply(seq_along(mlist), function(i) {
      mlist[[i]] == klist[[i]]
    })
    
    all.equal(hin, hon)
    [1] TRUE
    

    【讨论】:

    • 谢谢!这确实比 for 循环稍快。
    • 有点,真的吗?通常,这应该快得多。
    【解决方案2】:

    你可以考虑

    unlist(klist) == unlist(mlist)
    

    但这会丢弃列表格式。

    您可以通过比较来确定每个结果的原始索引

    cumsum(lengths(mlist))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-11
      • 2010-11-19
      相关资源
      最近更新 更多