r - 如何将频率分布转换为 R 中的概率分布

标签 r matrix probability apply frequency-distribution

我有一个包含 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 函数和/或告诉我如何优化我的函数以更快地执行?

最佳答案

这是一个尝试,但在数据帧而不是矩阵上:

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
)

enter image description here
#> 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,因此如果您要使用矩阵,我建议您考虑他的方法。

关于r - 如何将频率分布转换为 R 中的概率分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28267863/

相关文章:

r - 如何将字符串向量(每个给出命令)转换为 R 中的函数?

r - dplyr 中的表和 group_by

r - 有效地将数据从 data.table 转换为矩阵(速度和内存)

algorithm - 随机数递归

r - 获取在knitr中编织的文档类型

r - 为什么 expand.grid 比 data.table 的 CJ 快?

python - numpy/pandas/python 中用于搜索和替换的任何函数

python - 使用 numpy 计算距离矩阵的更快方法?

r - 枚举一系列不同概率的伯努利试验的所有可能的组合概率

arrays - 随机化两个值之间的矩阵元素,同时保持行和列总和固定 (MATLAB)