#r
#r
Вопрос:
Мне нужно было бы построить выровненные гистограммы на одном графике из строк матрицы. В следующем примере мне нужно будет построить 5 сложенных гистограмм. Однако команда hist отображает одну гистограмму всей матрицы. Есть ли какое-нибудь обходное решение, которое я мог бы использовать?
Заранее спасибо.
Артуро
x <- 10; y <- 10; g <- 5
dat <- matrix(rnorm((x y) * g), ncol = x y)
hist (dat)
Комментарии:
1. итак, вам нужны отдельные гистограммы для каждой строки, и вы хотите, чтобы они располагались вертикально для сравнения?
2. Это правильно. Каждая строка должна иметь свою собственную ось y и общую ось x.
Ответ №1:
ggplot
сделайте это легко (для этого нужны данные длинной формы).
library(tidyr); library(dplyr); library(ggplot2)
df <- dat %>% t() %>% as.data.frame() %>% gather(row) # chage data into a long format
Breaks <- hist(dat, plot=F)$breaks # get (or decide) breaks
ggplot(df, aes(x = value, fill = row)) geom_histogram(position = "stack", breaks = Breaks)
[ОТРЕДАКТИРОВАНО]
Это то, что вы хотите?
## original
ggplot(df, aes(x = value))
geom_histogram(breaks = Breaks)
facet_wrap(~ row) # make histogram par group.
## modified
ggplot(df, aes(x = value, fill = row)) # change fill colour
geom_histogram(breaks = Breaks)
facet_wrap(~ row, ncol = 1) # bring graphs into line
# facet_wrap( ~ row, ncol = 1, scales = "free_y") # if you don't want fixed scale
theme(strip.background = element_blank(), strip.text.x = element_blank()) # delete labels
[ОТРЕДАКТИРОВАНО 2: подход base_plot]
Базовый график экономит время.
## example data
x <- 1500; y <- 1500; g <- 30
set.seed(1); dat <- matrix(rnorm((x y) * g), ncol = x y)
## decide breaks
Breaks <- seq(-4.5, 4.5, 0.5)
## change par() to draw multiple graphs
par.old <- par(mar = c(0.1, 4.0, 0.1, 0.5), oma = c(4, 0, 0, 0), mfrow = c(nrow(dat), 1))
for(i in 1:nrow(dat)) {
hist(dat[,i], breaks = Breaks, xaxt = "n", xlab = "", main = "")
# grid(NULL)
}
par(new=T)
hist(dat[,nrow(dat)], breaks = Breaks, main = "", yaxt = "n",
xlab = "x", ylab = "", border = NA) # add x-axis
par(par.old)
Комментарии:
1. Спасибо, но мне нужно разделить каждую строку на моем графике, чтобы ее вклад был виден сразу
2. Спасибо. Это близко к тому, чего я хочу. Теперь мне нужно понять код .. 🙂
3. Также спасибо за прокомментированный код. У меня есть еще один вопрос, если вы не возражаете. Иногда мне нужно построить массивы размером до 30×6000, а не 5×20, как в приведенном мной примере. Я заметил, что в этом случае процедура занимает много времени. Я подумал, что, возможно, удаление цветов могло бы ускорить процесс. Считаете ли вы, что это было бы осуществимо?
4. @Arturo; К сожалению, насколько я знаю по своему опыту, цвета мало влияют на время. Конечно, вы можете удалить цвета гистограммы, удалив
fill = row
и изменив тему, просто вставив другую ggtheme раньшеtheme(strip...)
, например,... facet_wrap(~ row, ncol = 1) theme_minimal() theme(strip.background = element_blank(), strip.text.x = element_blank())
(см. ggtheme ). У меня нет хорошей идеи, как сэкономить время.5. @Arturo; Я добавил другой подход.
Ответ №2:
Это подход, который я использую для создания двух гистограмм на одном графике.
Рассмотрим набор данных, в котором столбец x является непрерывной переменной, а столбец y — факторной переменной; на каждом уровне будет получена одна гистограмма. Ниже приведен пример кода с использованием ggplot2:
OverlayedHist <- function(mData ,
featureVar ,
grouper ,
mbinwidth ,
mTitle ,
mxlab ,
mylab ,
mlegendTitle
){
# function name: OverlayedHist
# purpose: To produce overlayed histograms against a grouping variable
# Input:
# mData: dataset object in data.table format
# featureVar: name of continuous variable to produce histogram
# grouper: the grouping variable to produce the histogram
# mbinwidth: binwidth (see ggplot2 parameters)
# mTitle: Character to define title
# mxlab: Character to define xlab name
# mylab: Character to define ylab name
# mlegendTitle: Character to define legend title
library(data.table)
library(ggplot2)
library(plotly)
p <- ggplot(allDat, aes(eval(parse(text = featureVar)), fill = eval(parse(text = grouper))))
geom_histogram(alpha = 0.7, position = 'identity', binwidth = mbinwidth)
scale_fill_manual(values=c("#377EB8","#E41A1C"))
ggtitle(mTitle)
xlab(mxlab) ylab(mylab)
guides(fill=guide_legend(title=mlegendTitle)) theme(plot.title = element_text(size=10))
return(ggplotly(p))
}
Надеюсь, это поможет.
Приветствия! K.
Комментарии:
1. Не могли бы вы, пожалуйста, опубликовать какой-нибудь рабочий код для тестирования вашего метода?
2. Выше вы можете найти более подробную версию интерактивного сюжета