График рассеяния с ошибками
Как я могу создать следующий график в R? Точками, показанные на графике, являются средние значения, а их диапазоны соответствуют минимальным и максимальным значениям.
У меня есть данные в двух файлах (ниже приведен пример).
x y
1 0.8773
1 0.8722
1 0.8816
1 0.8834
1 0.8759
1 0.8890
1 0.8727
2 0.9047
2 0.9062
2 0.8998
2 0.9044
2 0.8960
.. ...
![enter image description here]()
Ответы
Ответ 1
Прежде всего: очень печально и неожиданно, что R не может выводить строки ошибок "из коробки" .
Вот мое любимое решение, преимущество в том, что вам не нужны дополнительные пакеты. Трюк состоит в том, чтобы нарисовать стрелки (!), Но с небольшими горизонтальными полосками вместо стрелок (!!!). Эта не столь простая идея исходит из R Wiki Tips и воспроизводится здесь как отработанный пример.
Предположим, что у вас есть вектор "средних значений" avg
и другой вектор "стандартных отклонений" sdev
, они имеют одинаковую длину n
. Позвольте сделать абсциссою только количество этих "измерений", поэтому x <- 1:n
. С их помощью приходят команды построения:
plot(x, avg,
ylim=range(c(avg-sdev, avg+sdev)),
pch=19, xlab="Measurements", ylab="Mean +/- SD",
main="Scatter plot with std.dev error bars"
)
# hack: we draw arrows but with very special "arrowheads"
arrows(x, avg-sdev, x, avg+sdev, length=0.05, angle=90, code=3)
Результат выглядит следующим образом:
![example scatter plot with std.dev error bars]()
В arrows(...)
функция length=0.05
- это размер "стрелочной головки" в дюймах, angle=90
указывает, что "стрелка" перпендикулярна оси стрелки, а особенно интуитивный параметр code=3
указывает что мы хотим нарисовать наконечник стрелы на обоих концах стрелки.
Для горизонтальных шкал ошибок необходимы следующие изменения, предполагая, что теперь вектор sdev
содержит ошибки в значениях x
, а значения y
- это ординаты:
plot(x, y,
xlim=range(c(x-sdev, x+sdev)),
pch=19,...)
# horizontal error bars
arrows(x-sdev, y, x+sdev, y, length=0.05, angle=90, code=3)
Ответ 2
Используя ggplot
и немного dplyr
для обработки данных:
set.seed(42)
df <- data.frame(x = rep(1:10,each=5), y = rnorm(50))
library(ggplot2)
library(dplyr)
df.summary <- df %>% group_by(x) %>%
summarize(ymin = min(y),
ymax = max(y),
ymean = mean(y))
ggplot(df.summary, aes(x = x, y = ymean)) +
geom_point(size = 2) +
geom_errorbar(aes(ymin = ymin, ymax = ymax))
Если есть дополнительный столбец группировки (в примере примера OP есть два errorbars на x значение, говоря, что данные получены из двух файлов), тогда вы должны получить все данные в одном кадре данных в начале, добавить переменную группировки в вызов dplyr::group_by
(например, group_by(x, file)
, если file
- имя столбца) и добавить его в качестве "групповой" эстетики в ggplot, например aes(x = x, y = ymean, group = file)
.
Ответ 3
#some example data
set.seed(42)
df <- data.frame(x = rep(1:10,each=5), y = rnorm(50))
#calculate mean, min and max for each x-value
library(plyr)
df2 <- ddply(df,.(x),function(df) c(mean=mean(df$y),min=min(df$y),max=max(df$y)))
#plot error bars
library(Hmisc)
with(df2,errbar(x,mean,max,min))
grid(nx=NA,ny=NULL)
Ответ 4
Другой способ (по крайней мере, для меня) ниже.
install.packages("ggplot2movies")
data(movies, package="ggplot2movies")
Средний размер участка по сравнению с рейтингом
rating_by_len = tapply(movies$length,
movies$rating,
mean)
plot(names(rating_by_len), rating_by_len, ylim=c(0, 200)
,xlab = "Rating", ylab = "Length", main="Average Rating by Movie Length", pch=21)
Добавить бары ошибок в график: mean - sd, mean + sd
sds = tapply(movies$length, movies$rating, sd)
upper = rating_by_len + sds
lower = rating_by_len - sds
segments(x0=as.numeric(names(rating_by_len)),
y0=lower,
y1=upper)
Надеюсь, что это поможет.
Ответ 5
Я собрал начало, чтобы закончить код гипотетического эксперимента с десятью измерениями, тиражированными три раза. Просто для удовольствия с помощью других stackoverflowers. Спасибо... Очевидно, что циклы - это опция, поскольку apply
можно использовать, но мне нравится видеть, что происходит.
#Create fake data
x <-rep(1:10, each =3)
y <- rnorm(30, mean=4,sd=1)
#Loop to get standard deviation from data
sd.y = NULL
for(i in 1:10){
sd.y[i] <- sd(y[(1+(i-1)*3):(3+(i-1)*3)])
}
sd.y<-rep(sd.y,each = 3)
#Loop to get mean from data
mean.y = NULL
for(i in 1:10){
mean.y[i] <- mean(y[(1+(i-1)*3):(3+(i-1)*3)])
}
mean.y<-rep(mean.y,each = 3)
#Put together the data to view it so far
data <- cbind(x, y, mean.y, sd.y)
#Make an empty matrix to fill with shrunk data
data.1 = matrix(data = NA, nrow=10, ncol = 4)
colnames(data.1) <- c("X","Y","MEAN","SD")
#Loop to put data into shrunk format
for(i in 1:10){
data.1[i,] <- data[(1+(i-1)*3),]
}
#Create atomic vectors for arrows
x <- data.1[,1]
mean.exp <- data.1[,3]
sd.exp <- data.1[,4]
#Plot the data
plot(x, mean.exp, ylim = range(c(mean.exp-sd.exp,mean.exp+sd.exp)))
abline(h = 4)
arrows(x, mean.exp-sd.exp, x, mean.exp+sd.exp, length=0.05, angle=90, code=3)