Несоответствие в биннинге функции cut в RStudio

#r

#r

Вопрос:

Вот некоторые эксперименты в RStudio с файлом RMarkdown:

 ---
title: "test"
author: "qed"
date: "10/10/2016"
output: html_document
---


```{r}
library(ISLR)
set.seed(3)
Wage$age = jitter(Wage$age)
get_breaks = function(cutted) {
  labels = levels(cutted)
  lower = as.numeric(sub("\((. ),.*", "\1", labels))
  upper = as.numeric(sub("[^,]*,([^]]*)\]", "\1", labels[length(labels)]))
  c(lower, upper)
}
age_groups = cut(Wage$age, 4)
age_groups1 = cut(Wage$age, get_breaks(age_groups))
all(levels(age_groups) == levels(age_groups1))
idx = which(age_groups != age_groups1)
idx # not empty!
```
  

Если вы свяжете его, вы увидите, что idx не является пустым.

Версия RStudio 0.99.903

R версия 3.3.1

По сути, я попытался извлечь разрывы из выходных данных функции cut и применить их явно. Ожидается, что новый вывод должен быть точно таким же, как и старый, но это не так.

Это ошибка? Как это исправить?


Редактировать

На самом деле, после неоднократных попыток сделать это в консоли R, оказывается, что там тоже существует та же проблема, так что это не ошибка RStudio. Еще более тревожным является то, что поведение не кажется детерминированным, несмотря set.seed на .

Комментарии:

1. Хм, странно. Какую версию R вы используете?

2. Действительно, после очистки все выглядит нормально. Но почему это должно иметь значение?

3. Если вы хотите воспроизводимое исследование, начните свой код с rm(list = ls())

4. Я не смог воспроизвести эту ошибку с помощью кода, предоставленного с R 3.3.1

5. Я обнаружил, что это происходит только в RStudio, а не в консоли R.

Ответ №1:

Вы думаете, что два способа обрезки вектора эквивалентны, но это не так. Эта проблема не имеет отношения к RStudio или knitr. Легко показать проблему в обычном сеансе R:

 problem = function() {
  library(ISLR)
  set.seed(NULL)  # reinitialize random seed
  Wage$age.jittered = jitter(Wage$age)
  get_breaks = function(cutted) {
    labels = levels(cutted)
    lower = as.numeric(sub("\((. ),.*", "\1", labels))
    upper = as.numeric(sub("[^,]*,([^]]*)\]", "\1", labels[length(labels)]))
    c(lower, upper)
  }
  age_groups = cut(Wage$age.jittered, 4)
  age_groups1 = cut(Wage$age.jittered, get_breaks(age_groups))
  all(levels(age_groups) == levels(age_groups1))
  idx = which(age_groups != age_groups1)
  length(idx)
}

res = replicate(1000, problem())
barplot(table(res))
  

частота длины (idx)

Можно было бы ожидать, что гистограмма будет иметь ненулевые частоты только при 0, но длина idx не равна нулю довольно много раз.

Возвращаясь к вашему вопросу, метки, которые вы видели, не обязательно являются точными конечными точками. Они могут быть округлены. Смотрите аргумент dig.lab на странице справки ?cut .