2014-01-28 1 views
3

Я создаю код для запуска и управления имитацией событий выборки на сайтах, которые могут находиться в одной из трех когорт сайтов. Я использую rep() присвоить идентификатор когорты (1,2 или 3), используя код ниже:Почему rep() ведет себя непоследовательно с этим простым примером R?

cohort <- rep(1:n.cohorts, n.sites) 

Я положил ключ линии первым, хотя воспроизвести мою проблему вам необходимо запустить следующие строки, которые выделите общее количество сайтов между когортами для представления на вызов rep().

n.cohorts <- 3 
s <- 10 # total available sites in this example 

# different proportions of the total can be allocated to each cohort, for example 
prop.control <- 0.4 ; prop.int <- 0.4 ; prop.ref <- 1-(prop.int+prop.control) 
n.control <- prop.control * s; n.int <- prop.int * s; n.ref <- prop.ref * s 
n.sites <- c(n.control, n.int, n.ref) 

теперь n.sites сама по себе возвращает

[1] 4 4 2

поэтому, когда я снова запустить свой cohort <- rep(1:n.cohorts, n.sites) вызов я ожидаю cohort быть список из 10 пунктов, примерно: [1] 1 1 1 1 2 2 2 2 3 3. Что я получить, однако, лишь 9:

> cohort 
[1] 1 1 1 1 2 2 2 2 3  

Если я запустить тот же код, в котором n.sites определяется непосредственно как так: n.sites <- c(4, 4, 2), я получаю 10 пунктов я ожидать. Я несколько раз переделал это, чтобы убедить себя, что по обоим сценариям n.sites сам по себе производит одинаковые результаты.

Может ли кто-нибудь объяснить, почему это происходит? Спасибо заранее.

Дэвид

ответ

2

Я думаю, что это один из тех вопросов, арифметических неточности в R. Проблемы здесь:

prop.ref <- 1-prop.int-prop.control 
prop.ref*10 
#[1] 2 
floor(prop.ref*10) 
#[1] 1 

Так г думает, что prop.int+prop.control очень немного больше, чем 0,8

Вы его можно установить на

cohort <- rep(1:n.cohorts, ceiling(n.sites)) 

Но вы Правильно, это действительно кажется, что серьезная ошибка EDIT - извините означает SEEM вроде серьезного

+0

Я бы сказал, вы прибил его. Так рад, что я спросил. После подтверждения вашего предложения я запустил 'print (prop.ref, dig = 20)' и ответ был «0.19999999999999995559'! – dhd

+1

Это НЕ ошибка. Это хорошо документированное поведение. 'rep' ожидает аргумент' integer', вы указываете 'numeric'. Преобразование «числовых» в «целое» всегда будет усекать дробную часть до точности машины. Попробуйте 'as.integer (1.99999999999999), 1.99999999999999'. Посмотрите на два результата. –

+0

извините @ SimonO'Hanlon; вы, конечно, правы, что это хорошо документировано, я имел в виду использовать SEEM, а не SERIOUS. Но для многих людей проблема присвоения очень неинтуитивная, т. Е. 'Prop.control <- 0.4; print (prop.int, dig = 20); # [1] 0.4000000000000000222', который является более числовым/числовым вопросом, нет? – Troy

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

  • Нет связанных вопросов^_^