首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免strsplit列表上的循环

避免strsplit列表上的循环
EN

Stack Overflow用户
提问于 2013-05-08 03:47:29
回答 3查看 1.5K关注 0票数 2

我有一个向量v,其中每个条目都是由分号分隔的一个或多个字符串(或可能的字符(0)):

代码语言:javascript
复制
ABC

DEF;ABC;QWE

TRF

character(0)

ABC;GFD

我需要找到包含"ABC“(1,2,5或逻辑向量T,T,F,F,T)的向量的索引。

我目前使用的循环如下:

代码语言:javascript
复制
toSelect=integer(0)
for(i in c(1:length(v))){
if(length(v[i])==0) next
words=strsplit(v[i],";")[[1]] 
if(!is.na(match("ABC",words))) toSelect=c(toSelect,i)
}

不幸的是,我的向量有45万个条目,所以这花费的时间太长了。我更喜欢通过如下操作来创建逻辑向量

代码语言:javascript
复制
toSelect=(!is.na(match("ABC",strsplit(v,";")))

但是因为strsplit返回一个列表,所以我找不到一种方法将strsplit(v,";")正确地格式化为一个向量(unlist不能做,因为它会破坏索引)。有没有人有任何关于如何加速这段代码的想法?

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2013-05-08 03:51:11

使用正则表达式:

代码语言:javascript
复制
v = list("ABC", "DEF;ABC;QWE", "TRF", character(0), "ABC;GFD")
grep("(^|;)ABC($|;)", v)
#[1] 1 2 5
票数 4
EN

Stack Overflow用户

发布于 2013-05-08 05:17:05

棘手的部分是处理character(0),@BlueMagister通过用character(1)替换它来进行模糊处理(这允许使用向量,但不允许表示原始问题)。也许吧

代码语言:javascript
复制
v <- list("ABC", "DEF;ABC;QWE", "TRF", character(0), "ABC;GFD")
v[sapply(v, length) != 0] <- strsplit(unlist(v), ";", fixed=TRUE)

来做字符串拆分。可以使用base R,但我建议您使用IRanges

代码语言:javascript
复制
source("http://bioconductor.org/biocLite.R")
biocLite("IRanges")

来安装,然后

代码语言:javascript
复制
library(IRanges)
w = CharacterList(v)

这给出了一个类似列表的结构,其中所有元素都必须是字符向量。

代码语言:javascript
复制
> w
CharacterList of length 5
[[1]] ABC
[[2]] DEF ABC QWE
[[3]] TRF
[[4]] character(0)
[[5]] ABC GFD

然后,人们可以做一些有趣的事情,比如问“元素成员是否等于ABC”

代码语言:javascript
复制
> w == "ABC"
LogicalList of length 5
[[1]] TRUE
[[2]] FALSE TRUE FALSE
[[3]] FALSE
[[4]] logical(0)
[[5]] TRUE FALSE

或“是否有任何元素成员等于ABC”

代码语言:javascript
复制
> any(w == "ABC")
[1]  TRUE  TRUE FALSE FALSE  TRUE

这将具有很好的伸缩性。对于不支持“开箱即用”的操作,策略(计算成本较低)是先unlist,然后转换为等长向量,然后使用原始CharacterList作为骨架进行relist,例如在每个成员上使用reverse

代码语言:javascript
复制
> relist(reverse(unlist(w)), w)
CharacterList of length 5
[[1]] CBA
[[2]] FED CBA EWQ
[[3]] FRT
[[4]] character(0)
[[5]] CBA DFG

正如@eddi指出的那样,这比grep慢。其动机是(a)避免需要制定复杂的正则表达式,同时(b)为像这样的结构化数据获得其他操作的灵活性。

票数 3
EN

Stack Overflow用户

发布于 2013-05-08 03:54:27

sapply%in%中使用strsplit

代码语言:javascript
复制
v <- c("ABC","DEF;ABC;QWE","TRF",character(1),"ABC;GFD")
sapply(strsplit(v,";"),function(x) "ABC" %in% x)
#[1]  TRUE  TRUE FALSE FALSE  TRUE
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16427290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档