信号包絡線処理をSPSS ModelerのR拡張ノードで行う

SPSS ModelerのR拡張ノードをつかって、センサーデータから以下の赤線のような信号包絡線を計算します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9a6b3a42-76d6-aa77-a8eb-d831ba7526c9.png)

* テスト環境
Modeler 18.4
Windows 11 64bit
R 4.0.5

信号包絡線処理は以下の記事のコードをそのまま引用させていただきました。

信号包絡線の計算 / Computing signal envelope 

https://www.geidai.ac.jp/~marui/r_program/envelope.html


* サンプルストリーム

https://github.com/hkwd/230303RExtension/raw/master/230303SignalEnvelope/SignalEnvelope2.str

* サンプルデータ

https://raw.githubusercontent.com/hkwd/230303RExtension/master/230303SignalEnvelope/sensor1000.csv


# 1. SPSS ModelerのR拡張ノードを利用可能にする。

R拡張ノードのセットアップができていない場合には以下の手順でセットアップします。

SPSS Modelerの拡張ノードでRを利用する

https://qiita.com/kawada2017/items/0bb68e0b577e02bb8c6a

# 2. 信号包絡線処理を行う。

今回用意したデータは以下です。
1分毎にセンター値が記録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c437a963-cc61-3a14-0d24-1156c4c4743d.png)

「時系列グラフ」でみると、以下のような振幅を持ったデータになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/011ecc40-f953-a757-8ab7-97b35b684147.png)

このデータに「拡張の変換」ノードを接続し、シンタックスとしてRを選び、以下のコードを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b8d52420-0f0c-f406-0c5c-355271f1d414.png)


```r:signalenvelope.r
#処理対象列の指定
x=as.matrix(modelerData$VAL)

###############################

#引用元:https://www.geidai.ac.jp/~marui/r_program/envelope.html
## ヒルベルト変換で解析信号を計算する（Hilbert Transform）
hilbert <- function(x) {
  # 信号長が奇数の時には末尾にゼロを加えて計算
  if (length(x) %% 2 == 1) {
    is.odd.flag <- TRUE
    x <- c(x, 0)
  } else {
    is.odd.flag <- FALSE
  }

  # ヒルベルト変換はフーリエ変換→負領域をゼロに→逆変換で計算
  X <- fft(x, inverse=FALSE)
  H <- c(1, rep(2, length.out=length(X)/2-1),
         1, rep(0, length.out=length(X)/2-1))
  Y <- X * H
  y <- fft(Y, inverse=TRUE) / length(Y)

  # 信号長が奇数の時には末尾につけたゼロの分を削除
  if (is.odd.flag == TRUE) {
    return(y[1:(length(y)-1)])
  } else {
    return(y)
  }
}
## 信号包絡線（Signal Envelope）
envelope <- function(x) {
  return(abs(hilbert(x)))
}

#信号包絡線処理
se <- envelope(x)

#print (se)

#Modelerに戻す
modelerData<-cbind(modelerData,se)
var1<-c(fieldName="se",fieldLabel="",fieldStorage="real",fieldMeasure="",fieldFormat="",fieldRole="")
modelerDataModel<-data.frame(modelerDataModel,var1)

```
「時系列グラフ」を実行すると、seという信号包絡線（赤）が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f8a396d8-29aa-636e-5380-10744700577c.png)

# 3. コードの解説

まず、処理対象列を選んでいます。この例では「VAL」という列なので、「modelerData$VAL」としています。

```r:処理対象列の指定.r
#処理対象列の指定
x=as.matrix(modelerData$VAL)
```

メインの処理のhilbert関数とenvelope関数は冒頭でも紹介した記事からそのままコピーしています。詳細は[この記事](https://www.geidai.ac.jp/~marui/r_program/envelope.html
)で詳しく説明されています。

この関数に処理対象列のデータをいれて、信号包絡線を得ています。

```r:信号包絡線処理.r
#信号包絡線処理
se <- envelope(x)
```

以下の部分で、得られた信号包絡線seを新規列として、Modelerに戻しています。
cbindで最終列に列追加を行い、var1で定義したse列情報のメタデータをmodelerDataModelに書き出しています。

```r:Modelerに戻す.r
#Modelerに戻す
modelerData<-cbind(modelerData,se)
var1<-c(fieldName="se",fieldLabel="",fieldStorage="real",fieldMeasure="",fieldFormat="",fieldRole="")
modelerDataModel<-data.frame(modelerDataModel,var1)

```

# 参考

#### SPSS ModelerのR拡張ノード関連記事へのリンク - Qiita 

https://qiita.com/kawada2017/items/131d7769ecb44043556e


#### SPSS ModelerのPython拡張ノード関連記事へのリンク - Qiita 

https://qiita.com/kawada2017/items/055ace72f9e1949004f3