是否可以在 R 上创建此图?

Is it possible to create this graph on R?

我是 R 的新手,我想创建一个类似于所附图表的图表。我尝试使用 ggplot 和基本程序创建密度图。

我使用了代码 ggplot(data, aes(x = Freq)) + geom_density() 但输出不正确。我在每个数字点上都出现了尖峰,而不是整体曲线。每一行是 1 到 7 之间的一个数据点,一个特征的频率分布如下:

1:500, 2:550 3:700 4:1000 5:900 6:835: 7:550

因此我有 5035 行,因为一行等于一个分数。

非常感谢任何帮助。

这是我希望的情节。 (注意我会在稍后阶段添加其他特征,我现在只想添加一行)。

这里有一些事情要做,首先是生成数据的汇总统计信息。您只需要以适当的方式调用 meansd 即可从数据中获取均值和标准差。您还没有显示您的数据,因此很难在这里提出很多建议。

就绘制这些汇总统计数据而言,您可以轻松地从原始论文中复制该图,但这很糟糕,我建议您不要这样做。更强的线条意味着更重要,需要双重标记所有内容,错误标记 y 轴,所有这些在绘制漂亮平滑的参数曲线之上都会给人一种错误的自信印象。我只扫描了论文,但那种数据迫切需要某种多层次模型

我更喜欢 "base" 图形,ggplot 非常适合探索图形,但如果您对图形的外观有严格的限制,它往往会妨碍您。我们从汇总统计数据开始:

df <- read.csv(text="
title,              mu, sigma,label, label_x,label_pos
Extraversion,       4.0, 1.08,Extra,    3.85,3
Agreeableness,      5.0, 0.77,Agree,    5.0, 3
Conscientiousness,  4.7, 0.97,Cons,     3.4, 2
Emotional stability,5.3, 0.84,Emot stab,5.9, 4
Intellect,          3.7, 0.86,Intellect,3.7, 3
")

我刚刚从论文中提取了数字,您必须计算它们。 mu 列是变量的平均值,sigma 是标准差。 label_xlabel_pos 用于绘制标签,因此需要手动选择(或者之后可以在 Inkscape 之类的软件中对绘图进行注释)。 label_x 是 x 轴位置,label_pos 代表相对于 x-y 点的位置(有关 pos 参数的信息,请参阅 text

接下来我们计算一些东西:

lwds <- 1 + seq(3, 1, len=5) ^ 2
label_y <- dnorm(df$label_x, df$mu, df$sigma)

即线宽和标签 y 位置,然后我们就可以开始绘制了:

# start by setting up plot nicely and setting plot limits
par(bty='l', mar=c(3, 3, 0.5, 0.5), mgp=c(1.8, 0.4, 0), tck=-0.02)
plot.new(); plot.window(c(1, 7), c(0, 0.56), yaxs='i')

# loop over data drawing curves
for (i in 1:nrow(df)) {
    curve(dnorm(x, df$mu[[i]], df$sigma[[i]]), add=T, n=151, lwd=lwds[[i]])
}

# draw labels
text(df$label_x, label_y, df$label, pos=df$label_pos)

# draw axes
axis(1, lwd=0, lwd.ticks=1)
axis(2, lwd=0, lwd.ticks=1)
box(lwd=1)

# finally, title and legend
title(xlab='Level of state', ylab='Probability density')
legend('topleft', legend=df$title, lwd=lwds, bty='n', cex=0.85)

这给了我们类似的东西:

我还使用了更现代的大写字母,并将 y 轴从零开始,因为这些是概率,所以不能为负数

我的偏好更接近于此:

细线覆盖均值周围 2 个标准差(即 95% 区间),粗线覆盖 1 个标准差 (68%),点就是均值。区分每个度量并比较它们要容易得多,而且它不会人为地使 "extraversion" 更加突出。代码类似:

par(bty='l', mar=c(3, 8, 0.5, 0.5), mgp=c(1.8, 0.4, 0), tck=-0.02)
plot.new(); plot.window(c(1, 7), c(5.3, 0.7))

# draw quantiles
for (i in 1:nrow(df)) {
    lines(df$mu[[i]] + df$sigma[[i]] * c(-1, 1), rep(i,2), lwd=3)
    lines(df$mu[[i]] + df$sigma[[i]] * c(-2, 2), rep(i,2), lwd=1)
}
# and means
points(df$mu, 1:5, pch=20)

axis(1, lwd=0, lwd.ticks=1)
axis(2, at=1:5, labels=df$title, lwd=0, lwd.ticks=1, las=1)
box()

title(xlab='Level of state')