56

如何在 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
..  ...

在此处输入图像描述

4

6 回答 6

141

首先:非常不幸和令人惊讶的是,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)

结果如下所示:

带有 std.dev 误差线的示例散点图

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)
于 2014-02-26T09:30:10.780 回答
11

使用ggplotand a littledplyr进行数据操作:

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的示例图每个x值有两个误差线,表示数据来自两个文件),那么您应该在一开始就将所有数据放在一个数据框中,将分组变量添加到dplyr::group_by调用中(例如,group_by(x, file)如果file是列的名称)并将其作为“组”美学添加到 ggplot 中,例如aes(x = x, y = ymean, group = file).

于 2015-04-23T16:16:38.727 回答
6
#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)
于 2012-10-23T16:09:15.217 回答
3

总结 Laryx Decidua 的回答:

定义和使用如下函数

plot.with.errorbars <- function(x, y, err, ylim=NULL, ...) {
  if (is.null(ylim))
    ylim <- c(min(y-err), max(y+err))
  plot(x, y, ylim=ylim, pch=19, ...)
  arrows(x, y-err, x, y+err, length=0.05, angle=90, code=3)
}

其中可以覆盖自动ylim,还可以传递额外的参数,例如mainxlabylab

于 2018-03-04T13:03:32.207 回答
1

另一种(更容易 - 至少对我来说)方法如下。

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)

希望有帮助。

于 2016-10-05T15:21:11.913 回答
-1

我把一个假设实验的代码从头到尾放在一起,重复了 10 次测量,重复了 3 次。在其他 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)
于 2015-04-23T15:38:58.237 回答