「スイープ」機能の使い方


100

Rパッケージのソースを見ると、関数が表示されています sweep頻繁に使用されるます。場合によっては、より単純な関数で十分な場合に使用されます(例:)apply。それ以外の場合は、コードブロックをステップ実行するためにかなりの時間を費やすことなく、何をしているのかを正確に知ることが不可能です。

sweepより単純な関数を使用しての効果を再現できるという事実は、私には理解できないことを示唆していますsweepのコアユースケースをことを示唆しており、この関数が頻繁に使用されるという事実は、それが非常に有用であることを示唆しています。

コンテキスト:

sweepRの標準ライブラリの関数です。その引数は次のとおりです。

sweep(x, MARGIN, STATS, FUN="-", check.margin=T, ...)

# x is the data
# STATS refers to the summary statistics which you wish to 'sweep out'
# FUN is the function used to carry out the sweep, "-" is the default

あなたが見ることができるように、引数は次のようにしているapplyもののsweep 1つ以上のパラメーターを必要ますSTATS

別の重要な違いはsweep同じ形状の配列を返すことです、入力配列に対して、apply渡された関数異なります。

sweep 動作中:

# e.g., use 'sweep' to express a given matrix in terms of distance from 
# the respective column mean

# create some data:
M = matrix( 1:12, ncol=3)

# calculate column-wise mean for M
dx = colMeans(M)

# now 'sweep' that summary statistic from M
sweep(M, 2, dx, FUN="-")

     [,1] [,2] [,3]
[1,] -1.5 -1.5 -1.5
[2,] -0.5 -0.5 -0.5
[3,]  0.5  0.5  0.5
[4,]  1.5  1.5  1.5

要約すると、私が探しているのは sweep

Rのドキュメンテーション、メーリングリスト、または「主要な」Rソースのいずれにも言及またはリンクしないでください。私がそれらを読んだと想定します。私が興味を持っているのは、経験豊富なRプログラマ/アナリストsweepが自分のコードでどのように使用するかです。


2
M-dxは結果を複製しません。あなた自身の質問に答えました。
John

applyこの結果について私が理解できる唯一の使用法はのようなものですがt(apply(t(M), 2, "-", dx))、それはかなり厄介です。
ケンウィリアムズ、

回答:


84

sweep()通常、行列を行または列で操作し、操作の他の入力が行/列ごとに異なる値である場合に使用されます。行と列のどちらで操作するかは、MARGINによって定義されapply()ます。私が「他の入力」と呼んだものに使用される値は、STATSによって定義されます。したがって、各行(または列)に対して、STATSから値を取得し、FUNによって定義された操作で使用します。

たとえば、定義した行列の1行目に1、2行目に2などを追加する場合は、次のようにします。

sweep (M, 1, c(1: 4), "+")

私は率直に言って、Rのドキュメントの定義も理解していませんでした。例を調べるだけで学びました。


2
少し言い換えると、STATSこの変数の悪いラベルのようです。これFUNは、マトリックスの各要素の値を変更するために使用される入力です(Mこの例では)。STATS選択したのサイズに一致するサイズの定数またはリスト/ベクトル/その他のいずれかMARGINです。おもう。
Roland

16

次に示すように、sweep()は、列ごとまたは行ごとに大きな行列を体系的に操作するのに最適です。

> print(size)
     Weight Waist Height
[1,]    130    26    140
[2,]    110    24    155
[3,]    118    25    142
[4,]    112    25    175
[5,]    128    26    170

> sweep(size, 2, c(10, 20, 30), "+")
     Weight Waist Height
[1,]    140    46    170
[2,]    120    44    185
[3,]    128    45    172
[4,]    122    45    205
[5,]    138    46    200

確かに、この例は単純ですが、STATSおよびFUN引数を変更すると、他の操作が可能になります。


6

この質問は少し古いですが、最近この問題に直面したため、スイープの一般的な使用法はcov.wt、重み付き共分散行列の計算に使用されるstats関数のソースコードにあります。R 3.0.1のコードを見ています。ここでsweepは、共分散を計算する前に列の平均を差し引くために使用されます。コードの19行目で、センタリングベクトルが導出されます。

 center <- if (center) 
        colSums(wt * x)
    else 0

そして54行目でマトリックスから一掃されます

x <- sqrt(wt) * sweep(x, 2, center, check.margin = FALSE)

コードの作成者はデフォルト値を使用FUN = "-"しているため、しばらく混乱しました。


3

1つの用途は、配列の加重和を計算する場合です。ここで、rowSums又はcolSums「重み= 1」を意味すると仮定することができるが、sweep重み付けされた結果を与える前に、このために使用することができます。これは、3次元以上の配列で特に役立ちます。

これは、たとえば、@ James Kingの例に従って加重共分散行列を計算するときに発生します。

現在のプロジェクトに基づく別の例を次に示します。

set.seed(1)
## 2x2x2 array
a1 <- array(as.integer(rnorm(8, 10, 5)), dim=c(2, 2, 2))
## 'element-wise' sum of matrices
## weights = 1
rowSums(a1, dims=2)
## weights
w1 <- c(3, 4)
## a1[, , 1] * 3;  a1[, , 2] * 4
a1 <- sweep(a1, MARGIN=3, STATS=w1, FUN="*")
rowSums(a1, dims=2)

0

sweep次のコードのように、関数を使用してデータをスケーリングおよび中央揃えできます。なお、ここmeanssdsは任意であることに注意してください(データに基づいて標準化したい参照値がある場合があります)。

df=matrix(sample.int(150, size = 100, replace = FALSE),5,5)

df_means=t(apply(df,2,mean))
df_sds=t(apply(df,2,sd))

df_T=sweep(sweep(df,2,df_means,"-"),2,df_sds,"/")*10+50

次のコードは、生のスコアをTスコアに変換します(mean = 50およびsd = 10)。

> df
     [,1] [,2] [,3] [,4] [,5]
[1,]  109    8   89   69   15
[2,]   85   13   25  150   26
[3,]   30   79   48    1  125
[4,]   56   74   23  140  100
[5,]  136  110  112   12   43
> df_T
         [,1]     [,2]     [,3]     [,4]     [,5]
[1,] 56.15561 39.03218 57.46965 49.22319 40.28305
[2,] 50.42946 40.15594 41.31905 60.87539 42.56695
[3,] 37.30704 54.98946 47.12317 39.44109 63.12203
[4,] 43.51037 53.86571 40.81435 59.43685 57.93136
[5,] 62.59752 61.95672 63.27377 41.02349 46.09661

1
@BenBolker回答で述べたように、現在のサンプル自体の平均値とsdではなく、参照平均値とsdに従って項目をスケーリングしたい場合があります。これは、大規模なサンプルで管理および標準化されているテストを処理し、統計に従って小さなサンプルスコアを標準化する場合に発生します。
Ehsan88 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.