2013-08-18 3 views
4

Я программист на C++, и я новичок в R. Кто-то сказал мне, что использование цикла for в R - плохая идея и что лучше использовать sapply. Я написал следующий код, чтобы вычислить вероятность birthday coincidence:sapply in R, способ использования?

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])) 

Но как использовать формулу для несовместимости с днем ​​рождения?

+1

'M' никогда не определяется. Что это должно быть? – Dason

+2

Всегда остерегайтесь «кто-то». Он полон идей, но часто без надежной атрибуции. –

+0

@CarlWitthoft спасибо :) – Edwardo

ответ

6

Вы можете сделать:

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_along и seq_len, которые являются более надежными, чем : при работе с векторами нулевой длины.)

+0

Wow! поэтому seq_along и seq_len быстрее, чем 1: что-то? также cumprod? Где я могу научиться писать хороший и быстрый код с R? Благодаря! – Edwardo

+0

Кроме того, что, если я хочу напечатать какое-то вмешательство? например, когда вероятность составляет менее 50%? Я знаю, как это сделать, но как с помощью sapply? или cumprod? @flodel – Edwardo

+0

'seq_along' и' seq_len' не быстрее, они безопаснее: посмотрите, что '1: x' даст вам, когда' x' равно нулю. Если вы хотите печатать случаи, когда 'prob'' <0,5', вы можете: 1) изменить функцию, которую вы 'sapply', например. 'function (x) {y <- prod (m [1: x]); if (y <50) print (x); return (y)} 'или 2), используйте что-то векторизованное:' which (вероятность <0.5) '. – flodel

4

Для вас конкретный вопрос, он, вероятно, лучше всего использовать встроенный в день рождения вероятностный калькулятор

sapply(1:50, pbirthday) 
+0

Блестящий. Кто-то прикрывает каждую случайность. – dardisco

+0

Спасибо, но я хочу сделать это, чтобы получить больше информации и опыта с R. – Edwardo

+0

@Edwardo вы можете взглянуть на исходный код 'pbirthday', чтобы узнать, как автор напал на эту вероятностную проблему. –

Смежные вопросы