Построение гистограммы с различным равенством границ

Я хотел бы построить гистограмму, где сегменты указаны следующим образом:

• 4.25 ≤ E < 4.75
• 4.75 ≤ E < 4.90
• 4.90 ≤ E ≤ 5.10
• 5.10 < E < 5.25
• 5.25 ≤ E ≤ 5.75

Обратите внимание, как прыгает равенство между левой и правой границей. Как я могу сделать это в коде?

1 ответ

Решение

Насколько я знаю, в базе R нет функции вырезания / разрыва, которая позволяла бы вам определять такие нерегулярные разрывы, подобные этой. Вы могли бы обернуть findInterval сделать некоторые манипуляции

findInterval2 <- function(x, br, rightmost.closed = FALSE, left.closed=TRUE,
    trim=FALSE, labels=NULL) {
    r <- findInterval(x, br, rightmost.closed)
    closed.left <- c(rep_len(left.closed, length(br)), rightmost.closed)
    m <- x %in% br
    slideright <- m & r==0 & !left.closed[1]
    r[slideright] <- r[slideright] + 1
    slideleft <- which(m & r!=0 & !left.closed[ifelse(r==0,NA,r)])
    r[slideleft] <- r[slideleft]-1
    rng <- 0:length(br)
    if(trim) {
        r[r<1 | r>length(br)-1] <- NA
        rng <- 1:(length(br)-1)
    }
    if (is.null(labels) || (is.logical(labels) && labels==TRUE)) {
        ff <- format(embed(br,2))
        labels <- paste0(
            ifelse(left.closed, "[","("), 
            ff[,2], ", ", ff[,1], 
           ifelse(c(left.closed[-1], rightmost.closed), ")","]")
        )
        if(!trim) {
            labels <- c(
                paste0("(-Inf,", ff[1,2], ifelse(left.closed[1], ")","]") ),
                labels,
                paste0( ifelse(rightmost.closed, "[","("), ff[nrow(ff),1], ", Inf)" )
            )
        }
    } else if (is.logical(labels) && labels==FALSE) {
        labels = NULL
    }
    if (!is.null(labels)) {
        r <- factor(r, levels=rng, labels=labels)
    }
    r
}

Со списком перерывов br<-c(4.25 ,4.75, 4.90,5.10, 5.25, 5.75)Нормальное поведение findInterval создает перерывы / метки с

  • -inf < x < 4.25: 0
  • 4.25 <= x < 4.75: 1
  • 4.75 <= x < 4.90: 2
  • 4.90 <= x < 5.10: 3
  • 5.10 <= x < 5.25: 4
  • 5.25 <= x < 5.75: 5
  • x>=5.75: 6

Однако, если мы добавим наш новый параметр left.closed, мы указываем, должен ли каждый из регионов, указанных парами значений разрыва, оставаться закрытыми (по умолчанию) или закрытыми вправо. Этот вектор должен иметь длину на единицу меньше длины вектора разрыва.

Мы могли бы получить перерывы, которые вы хотите с

rr <- findInterval2(x, br, rightmost.closed=FALSE, 
    left.closed=c(T, T, T, F, T), trim=TRUE) 

который должен создать

  • 4.25 <= E < 4.75: 1
  • 4.75 <= E < 4.90: 2
  • 4.90 <= E <= 5.10: 3
  • 5.10 < E < 5.25: 4
  • 5.25 <= E <= 5.75: 5

Обратите внимание, что проверка на точное совпадение с числовыми (десятичными) значениями очень грязная. Таким образом, выполнение этого материала с непрерывными данными потенциально ошибочно.

Также обратите внимание, что это не обязательно относится непосредственно к гистограммам. Эту функцию можно использовать для группировки, а затем для создания barplot если вы хотите визуализировать данные. Гистограммы действительно предназначены только для оценки базовой плотности непрерывных случайных величин, и, если они слишком разборчивы в отношении точек разрыва, кажется, что ваши данные могут быть более дискретными, и вы заинтересованы в количестве, а не в плотности.

Например, мы можем создать тестовые данные с

set.seed(15)
br <- c(4.25,4.75, 4.90, 5.10, 5.25, 5.75)
x <- runif(45, min(br), max(br))
rr <- findInterval2(x, br, rightmost.closed=FALSE, 
    left.closed=c(T, T, T, F, T), trim=TRUE)

barplot(table(rr))

Другие вопросы по тегам