比较相同向量的相邻元素(避免循环)

Luc*_*ion 5 r vector string-comparison sapply

我设法写了一个for loop比较以下向量中的字母:

bases <- c("G","C","A","T")
test <- sample(bases, replace=T, 20)
Run Code Online (Sandbox Code Playgroud)

test 将返回

[1] "T" "G" "T" "G" "C" "A" "A" "G" "A" "C" "A" "T" "T" "T" "T" "C" "A" "G" "G" "C"
Run Code Online (Sandbox Code Playgroud)

通过该功能,Comp()我可以检查字母是否与下一个字母匹配

Comp <- function(data)
{
    output <- vector()
    for(i in 1:(length(data)-1))
    {
    if(data[i]==data[i+1])
        {
        output[i] <-1
        }
        else
        {
        output[i] <-0
        }
    }
    return(output)
}
Run Code Online (Sandbox Code Playgroud)

导致;

> Comp(test)
 [1] 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0
Run Code Online (Sandbox Code Playgroud)

这是有效的,但是它的数量很大.因此我试过了sapply()

Comp <- function(x,i) if(x[i]==x[i+1]) 1 else 0
unlist(lapply(test, Comp, test))
Run Code Online (Sandbox Code Playgroud)

不幸的是它没有工作...(Error in i + 1 : non-numeric argument to binary operator)我无法弄清楚如何访问向量中的前一个字母来比较它.另外length(data)-1,"不比较"最后一个字母可能会成为一个问题.

谢谢大家的帮助!

干杯幸运

Jos*_*ich 13

只是"滞后" test和使用==,这是矢量化.

bases <- c("G","C","A","T")
set.seed(21)
test <- sample(bases, replace=TRUE, 20)
lag.test <- c(tail(test,-1),NA)
#lag.test <- c(NA,head(test,-1))
test == lag.test
Run Code Online (Sandbox Code Playgroud)

更新:

此外,您的Comp功能很慢,因为您没有指定output初始化时的长度.我怀疑你正在尝试预分配,但是vector()创建了一个零长度向量,必须在循环的每次迭代期间进行扩展.你Comp如果更改呼叫功能是显著快vector()vector(length=NROW(data)-1).

set.seed(21)
test <- sample(bases, replace=T, 1e5)
system.time(orig <- Comp(test))
#    user  system elapsed 
#  34.760   0.010  34.884 
system.time(prealloc <- Comp.prealloc(test))
#    user  system elapsed 
#    1.18    0.00    1.19 
identical(orig, prealloc)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)