1

この小さなコードスニペットは、ソートされたデータフレームをループすることになっています。これは、列aIndexとcIndex、およびbIndexとdIndexに同じ情報を持つ連続する行の数をカウントします。これらが同じである場合は、カウントをデポジットして次回の増分を行い、異なる場合は、カウントをデポジットして次回の1にリセットします。

for (i in 1:nrow(myFrame)) {
  if (myFrame[i, aIndex] == myFrame[i, cIndex] &
    myFrame[i, bIndex] == myFrame[i, dIndex]) {
      myFrame[i, eIndex] <- count
      count <- (count + 1)
  } else {
      myFrame[i, eIndex] <- count
      count <- 1
  }
}

長い間稼働しています。可能な限りベクトル化することになっていることは理解していますが、ここでは実際には見ていません。これを速くするために私は何をすべきですか?

実行後の数行の例は次のとおりです。

aIndex bIndex cIndex dIndex eIndex
     1      2      1      2      1
     1      2      1      2      2
     1      2      4      8      3
     4      8      1      4      1
     1      4      1      4      1
4

2 に答える 2

2

これであなたが望むことができると思います。トリッキーな部分は、違いのeIndexにカウントがリセットされることです。これにより、 .

これを行うためのより簡単な方法が (うまくいけば) ありますが、これが私が思いついた方法です。

tmprle <- rle(((myFrame$aIndex == myFrame$cIndex) & 
               (myFrame$bIndex == myFrame$dIndex)))
myFrame$eIndex <- c(1,
                    unlist(ifelse(tmprle$values, 
                                  Vectorize(seq.default)(from = 2,
                                                         length = tmprle$lengths), 
                                  lapply(tmprle$lengths, 
                                         function(x) {rep(1, each = x)})))
                    )[-(nrow(myFrame)+1)]

を与える

> myFrame
  aIndex bIndex cIndex dIndex eIndex
1      1      2      1      2      1
2      1      2      1      2      2
3      1      2      4      8      3
4      4      8      1      4      1
5      1      4      1      4      1
于 2012-05-21T17:11:52.480 に答える
2

多分これはうまくいくでしょう。rlesequenceビットを作り直しました。

dat <- read.table(text="aIndex bIndex cIndex dIndex
1 2 1 2
1 2 1 2
1 2 4 8
4 8 1 4
1 4 1 4", header=TRUE, as.is=TRUE,sep = " ")
dat$eIndex <-NA
#identify rows where a=c and b=d, multiply by 1 to get a numeric vector
dat$id<-(dat$aIndex==dat$cIndex & dat$bIndex==dat$dIndex)*1
#identify sequence
runs <- rle(dat$id)
#create sequence, multiply by id to keep only identicals, +1 at the end
count <-sequence(runs$lengths)*dat$id+1
#shift sequence down one notch, start with 1
dat$eIndex <-c(1,count[-length(count)])
dat

  aIndex bIndex cIndex dIndex eIndex id
1      1      2      1      2      1  1
2      1      2      1      2      2  1
3      1      2      4      8      3  0
4      4      8      1      4      1  0
5      1      4      1      4      1  1
于 2012-05-21T19:59:39.327 に答える