0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【R】ベクトル中のある長さまでの連続した数値を他の数値に置き換える

Last updated at Posted at 2022-07-05

計測結果を処理する為に、次のようなベクトルの中の、0が1~4回連続する部分を1に置き換える必要が出てきました。
c(1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0)

c(1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0)

この方法、簡単そうに見えるのですが、なかなかできずに四苦八苦しました。
結局、下記の書き込みを参照してようやく解決出来ました。
https://tagsqa.com/detail/29800

rleという関数を使うのですが、最初に書いたベクトルを代入してみます。

rle(c(1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0))
Run Length Encoding
  lengths: int [1:8] 2 6 6 4 6 2 1 6
  values : num [1:8] 1 0 1 0 1 0 1 0

少しとっつきにくいのですが、このように、長さと値が返ってきます。
さらに
inverse.rle
という逆変換をしてくれる機能が素晴らしく使えます。
例えば下記のようになります。

value <- c(1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0)
r <- rle(value)
 
# 代入します
r$values[1] <- 9
 
# 値を見てみます
r$lengths
[1] 2 6 6 4 6 2 1 6
r$values
[1] 9 0 1 0 1 0 1 0

inverse.rle(r)
 [1] 9 9 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0

このように、最初のデータフレームの2連続の1を9に置き換えた答えが返ってきます。

そこで冒頭の問題を解決する関数を作ってみました。

paste_0to1 <- function (data) {
  r <- rle(data)
  rev <- abs(r$values - 1)
  len <- rev * r$lengths
  flag <- which((len < 5) & (len != 0))
  r$values[flag] <- 1
  return(inverse.rle(r))
}

皆様の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?