我有一个df阶层,每个阶层都有1000个样本,该样本来自该阶层的估计值的后验分布。

mydf <- as.data.frame(lapply(seq(1, 1000), rnorm, n=100))
colnames(mydf) <- paste('s', seq(1, ncol(mydf)), sep='')

我想为每行分配一些分位数的列。在经典R中,我会写这个。
quants <- t(apply(mydf, 1, quantile, probs=c(.025, .5, .975)))
colnames(quants) <- c('s_lo', 's_med', 's_hi')
mydf <- cbind(mydf, quants)

我怀疑dplyr(也许是rowwise?)中有直接的方法,但是我的尝试失败了。有想法吗?

最佳答案

dplyr并未针对基于行的计算进行优化。尽管您可以使用rowwise()做到这一点,但我还是建议不要这样做:性能会很糟糕。最好的速度可能是期望使用matrix的东西,并且可以对行进行操作。我建议apply

为了简洁起见,我将不处理100x1000 data.frame,而是使用5列:

set.seed(2)
mydf <- as.data.frame(lapply(seq(1, 5), rnorm, n=10))
colnames(mydf) <- paste('s', seq(1, ncol(mydf)), sep='')

仅当所有列都具有相同的matrix时,才转换为class是合理的。在这种情况下,它们都是numeric,所以我们很安全。 (如果数据框中有非数字列,请仅在此处提取所需的列,然后将它们绑定(bind)回去。)
mymtx <- as.matrix(mydf)
apply(mymtx, 1, quantile, c(0.1, 0.9))
#         [,1]     [,2]     [,3]     [,4]     [,5]       [,6]     [,7]     [,8]     [,9]    [,10]
# 10% 1.028912 1.430939 1.999521 0.305907 1.753824 0.03267599 1.934381 1.270504 2.995816 1.489634
# 90% 4.950067 3.807735 4.881554 6.123989 4.886388 5.55628806 4.207605 4.184460 4.406384 3.782134

像这样使用apply时值得注意的是,结果是基于行的形式,可能与人们期望的结果相反。只需将其包装在t(...)中,您将看到您可能期望的列。

可以使用cbind或类似函数将其与原始数据帧重新组合。

可以在这样的管道中完成此操作:
mydf %>%
  bind_cols(as.data.frame(t(apply(., 1, quantile, c(0.1, 0.9)))))
#            s1         s2        s3       s4       s5        10%      90%
# 1   0.1030855  2.4176508 5.0908192 4.738939 4.616414 1.02891157 4.950067
# 2   1.1848492  2.9817528 1.8000742 4.318960 3.040897 1.43093918 3.807735
# 3   2.5878453  1.6073046 4.5896382 5.076164 4.158295 1.99952092 4.881554
# 4  -0.1303757  0.9603310 4.9546516 3.715842 6.903547 0.30590700 6.123989
# 5   0.9197482  3.7822290 3.0049378 3.223325 5.622494 1.75382406 4.886388
# 6   1.1324203 -0.3110691 0.5482936 3.404340 6.990920 0.03267599 5.556288
# 7   1.7079547  2.8786046 3.4772373 2.274020 4.694516 1.93438093 4.207605
# 8   0.7603020  2.0358067 2.4034418 3.097416 4.909156 1.27050387 4.184460
# 9   2.9844739  3.0128287 3.7922033 3.440938 4.815839 2.99581584 4.406384
# 10  0.8612130  2.4322652 3.2896367 3.753487 3.801232 1.48963385 3.782134

我将列名留给您。

关于r - dplyr用于行分位数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43480362/

10-11 07:49