3

n 行の観測値を持つ行列があります。観測値は、特徴の度数分布です。頻度分布を、各行の合計が 1 である確率分布に変換したいと思います。したがって、行列の各要素は、要素の行の合計で除算する必要があります。

作業を行う次の R 関数を作成しましたが、大きな行列では非常に遅くなります。

prob_dist <- function(x) {

    row_prob_dist <- function(row) {
       return (t(lapply(row, function(x,y=sum(row)) x/y)))
       }

    for (i in 1:nrow(x)) {
       if (i==1) p_dist <- row_prob_dist(x[i,])
       else p_dist <- rbind(p_dist, row_prob_dist(x[i,]))
       }
    return(p_dist)
}

B = matrix(c(2, 4, 3, 1, 5, 7), nrow=3, ncol=2)
B
     [,1] [,2]
[1,]    2    1
[2,]    4    5
[3,]    3    7

prob_dist(B)
     [,1]      [,2]    
[1,] 0.6666667 0.3333333
[2,] 0.4444444 0.5555556
[3,] 0.3       0.7     

仕事をするR関数を提案したり、関数を最適化してより高速に実行する方法を教えてもらえますか?

4

4 に答える 4

5

これは試みですが、マトリックスではなくデータフレームで:

df <- data.frame(replicate(100,sample(1:10, 10e4, rep=TRUE)))

dplyr私はアプローチを試みました:

library(dplyr)
df %>% mutate(rs = rowSums(.)) %>% mutate_each(funs(. / rs), -rs) %>% select(-rs)

結果は次のとおりです。

library(microbenchmark) 
mbm = microbenchmark(
dplyr = df %>% mutate(rs = rowSums(.)) %>% mutate_each(funs(. / rs), -rs) %>% select(-rs),
t = t(t(df) / rep(rowSums(df), each=ncol(df))),
apply = t(apply(df, 1, prop.table)),
times = 100
)

ここに画像の説明を入力

#> mbm
#Unit: milliseconds
#  expr       min        lq      mean    median        uq       max neval
# dplyr  123.1894  124.1664  137.7076  127.3376  131.1523  445.8857   100
#     t  384.6002  390.2353  415.6141  394.8121  408.6669  787.2694   100
# apply 1425.0576 1520.7925 1646.0082 1599.1109 1734.3689 2196.5003   100

編集:@DavidベンチマークはOPとより一致しているため、マトリックスを使用する場合は彼のアプローチを検討することをお勧めします.

于 2015-02-01T23:50:01.110 に答える