R の行列の効率的なサブセット化と列加算

okwaves2024-01-25  9

ばかげた質問でしたら申し訳ありません。コードを最適化したいと考えていますが、R の初心者なので、どこから始めればよいのかわかりません。

行列 X があり、その行は y の要素によってラベル付けされています。ラベルのセットは数値であり、{1,...,K} で構成されます。さまざまなラベルに対応する各部分行列の列の合計を計算し、それを M に保存できるようにしたいと考えています。これをより明確にするために、現在のコードを提供します。

for (i in 1:K) {
    cluster = (y == i)
    if (any(cluster)) {
      clusterRows = X[cluster, , drop = F]
      M[i, ] = colSums(clusterRows)
    }
}

これを行うための、より適切で効率的な方法はありますか?効率的とは、実行時間のことです。

編集: 例。

入力:

set.seed(1)
X = matrix(rnorm(100*2), nrow = 100, ncol = 2)
y = rep(1:2, 50)
M = matrix(rep(0,4), 2)
K = 2

出力:

       [,1]      [,2]
[1,] 9.776280 -2.595435
[2,] 1.112457 -1.185373

編集 2: Base 以外のライブラリは使用していません。 これが私の sessionInfo() です:

R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Linux Mint 19.3

Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] microbenchmark_1.4-7 compiler_3.4.4       tools_3.4.4  

3

サンプル データと予想される出力を共有してください。このような場合、目標が実行時の効率である場合、サンプル データを共有する最良の方法は、適切なサンプル データをシミュレート/作成するコードを共有することです。 (ランダム性を再現できるように set.seed() を使用してください。) 再現可能な例を作成するためのその他のヒントについては、この FAQ をご覧ください。

– グレゴール・トーマス

2020 年 9 月 4 日 22:23

追加しましたe 入力/出力 + sessionInfo()。

– レナト・セルガジノフ

2020 年 9 月 4 日 22:56

1

これを機能させるには、M 行列を作成する必要があります。 M <- 行列(rep(0,4), 2)?

– 疑似スピン

2020 年 9 月 4 日 23:00

適切な編集を行いました。申し訳ありませんが、それを含めるのを忘れていました。

– レナトセルガジノフ

2020 年 9 月 4 日 23:09



------------------------

必要なのは、ベース R の rowsum() 関数だと思います。この関数は行列の各列を取得し、グループ列またはグループに従ってこれらの列の各行を折りたたむ (または合計します)。ベクター。これは、https://www.brodieg.com/2019/08/22/hydra-loose-ends/ でわかるように、非常に高速な関数なので、おそらくあなたが望むものです。

入力は次のとおりです。

set.seed(1)
X = matrix(rnorm(100*2), nrow = 100, ncol = 2)
y = rep(1:2, 50)
M = matrix(rep(0,4), 2)
K = 2

これが関数です:

rowsum(X, y)

結果は次のとおりです。

      [,1]      [,2]
1 9.776280 -2.595435
2 1.112457 -1.185373



------------------------

ベース R からの集計を使用できます

aggregate(X ~ y, FUN = sum)

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。