【问题标题】:sapply in R, how to use?sapply 在 R 中,如何使用?
【发布时间】:2013-08-18 23:35:09
【问题描述】:

我是一名 C++ 程序员,而且我是 R 新手。有人告诉我,在 R 中使用 for 循环是个坏主意,最好使用 sapply。我写了以下代码来计算birthday coincidence的概率:

prob <- 1           # prob of no coincidence
days <- 365 
k <- 50             # how many people
probability <- numeric()  #probability vector (empty right now)
for(i in 1:k){
    prob <- (days - i + 1)/days * prob # Formula for no coincidence
    probability[i] <- 1 - prob
}

我怎样才能用sapply 做同样的事情?我想做类似的事情:

1 - sapply(1:length(m), function(x) prod(m[1:x]))

但是如何使用公式来确定生日不重合呢?

【问题讨论】:

  • m 从未定义。它应该是什么?
  • 永远提防“某人”。他满脑子都是想法,但往往没有可靠的出处。
  • @CarlWitthoft 谢谢 :)

标签: r sapply


【解决方案1】:

你可以这样做:

m <- (days - seq_len(k) + 1) / days
probability <- 1 - sapply(seq_along(m), function(x) prod(m[1:x]))

但有用的cumprod 函数会缺少:

probability <- 1 - cumprod(m)

这样会快很多。

(在处理零长度向量时,seq_alongseq_len: 更稳健。)

【讨论】:

  • 哇!所以 seq_along 和 seq_len 比 1:something 更快?也 cumprod?我在哪里可以学习用 R 编写更好更快的代码?谢谢!
  • 另外,如果我想打印一些交互怎么办?例如,当概率小于 50% 时?我知道如何在 for 中做到这一点,但是如何使用 sapply?还是 cumprod? @flodel
  • seq_alongseq_len 不是更快,而是更安全:看看当x 为零时1:x 会给你什么。如果要打印prob&lt; 0.5 的情况,可以 1) 修改sapply 的功能,例如function(x){y &lt;- prod(m[1:x]); if (y &lt; 50) print(x); return(y)} 或 2) 再次使用矢量化的东西:which(probability &lt; 0.5)
【解决方案2】:

对于您的具体问题,最好只使用内置的生日概率计算器

sapply(1:50, pbirthday)

【讨论】:

  • 太棒了。有人在报道每一种可能性。
  • 谢谢,但我想这样做只是为了获得更多关于 R 的信息和经验。
  • @Edwardo 你可以看看pbirthday 的源代码,看看作者是如何解决这个概率问题的。
  • @CarlWitthoft 如何在 R 中查看生日的源代码?
  • @Edwardo 只需输入pbirthday
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多