【问题标题】:Compact way to filter a vector base on two vectors of position in R基于R中两个位置向量过滤向量的紧凑方法
【发布时间】:2021-02-03 01:16:27
【问题描述】:

我有一个文本向量,例如

library(stringi)
MWE <- stri_rand_strings(200, 10, pattern = "[A-Za-z0-9]")

我的实际示例不是随机的,因此我可以找到一些我想要保留的模式的重复出现。 因此,我能够grep 我的模式的开始和结束,并获得两个向量:

sequence_start <- c(9,44,56,73,85,98,110,122,140,152,164,176,188)
sequence_end <- c(14,49,61,78,91,103,115,127,145,157,169,181,193)

这是 easy 模式,所以我的几乎所有序列的长度都是 5,但 1. 一个是 6 和 2。出于更一般的原因,我想从提到的两个向量。

我想要的输出是基于上述开始和结束序列的我的 MWE 的提取序列,即MWE[9:14], MWE[44:49] etc.

我可以使用for 循环来做到这一点(虽然我有一个警告):

Desired_Output <- rep(NA,length(sequence_start))
for (i in (1:length(sequence_start))){
  Desired_Output[i] = MWE[sequence_start[i]:sequence_end[i]]
}

但是我尝试提高一点我的编码技能,并且已经理解应该尽可能避免 for 循环,所以我想知道有什么更好的方法可以做到这一点。 我对输出的格式持开放态度。理想情况下,代码可读性是一个因素,因为我与 R 语言比我更不流利的人一起工作!

【问题讨论】:

    标签: r performance data-manipulation code-readability


    【解决方案1】:

    没有显式循环的一个选项是使用Map()

    MWE[unlist(Map(seq, sequence_start, sequence_end))]
    

    除非毫秒很重要,否则我认为循环很好。但我不认为当前循环正在做你想要的?这是一个修改:

    Desired_Output <- list()
    for (i in (1:length(sequence_start))){
      Desired_Output[[i]] = MWE[sequence_start[i]:sequence_end[i]]
    }
    Desired_Output <- unlist(Desired_Output)
    

    【讨论】:

    • 谢谢,它有效。实际上,我认为列出的选项更适合我。如何调整第一个选项以获得第二个的列表结果?
    • 可能是lapply(Map(seq, sequence_start, sequence_end), function(x) MWE[x])lapply(seq_along(sequence_start), function(i) MWE[sequence_start[i]:sequence_end[i]])
    • 我想第二个选项是效率和可读性之间的一个很好的折衷方案,非常感谢
    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多