6

for loop次のベクトルで文字を比較するa を書くことができました。

bases <- c("G","C","A","T")
test <- sample(bases, replace=T, 20)

test戻ります

[1] "T" "G" "T" "G" "C" "A" "A" "G" "A" "C" "A" "T" "T" "T" "T" "C" "A" "G" "G" "C"

関数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)
}

その結果;

> Comp(test)
 [1] 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0

これは機能していますが、数が多いと非常に遅くなります。そのため、私は試しましたsapply()

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

残念ながら動作しません... ( Error in i + 1 : non-numeric argument to binary operator) ベクター内の前の文字にアクセスして比較する方法がわかりません。また、length(data)-1最後の文字を「比較しない」ことも問題になる可能性があります。

助けてくれてありがとう!

乾杯ラッキー

4

3 に答える 3

14

「遅れて」ベクトル化された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

アップデート:

また、関数を初期化するときに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
于 2011-08-05T11:24:33.517 に答える
3

@Joshuaが書いたように、もちろんベクトル化を使用する必要があります-より効率的です。...しかし、参考までに、Comp関数はまだ少し最適化できます。

比較の結果は、TRUE/FALSEどれが の美化されたバージョンであるか1/0です。また、結果が数値ではなく整数であることを確認すると、メモリの半分が消費されます。

Comp.opt <- function(data)
{
    output <- integer(length(data)-1L)
    for(i in seq_along(output))
    {
        output[[i]] <- (data[[i]]==data[[i+1L]])
    }
    return(output)
}

...そして速度の違い:

> system.time(orig <- Comp(test))
   user  system elapsed 
  21.10    0.00   21.11 
> system.time(prealloc <- Comp.prealloc(test))
   user  system elapsed 
   0.49    0.00    0.49 
> system.time(opt <- Comp.opt(test))
   user  system elapsed 
   0.41    0.00    0.40 
> all.equal(opt, orig) # opt is integer, orig is double
[1] TRUE
于 2011-08-05T15:53:21.820 に答える
1

これを見てください:

> x = c("T", "G", "T", "G", "G","T","T","T")
> 
> res = sequence(rle(x)$lengths)-1
> 
> dt = data.frame(x,res)
> 
> dt
  x res
1 T   0
2 G   0
3 T   0
4 G   0
5 G   1
6 T   0
7 T   1
8 T   2

より速く動作する可能性があります。

于 2015-08-07T10:37:22.510 に答える