使用 ggplot2 在 1 graph/axes 上绘制对应于多个列的多个图,由索引指定

Plot multiple plots corresponding to multiple columns, specified by index, on 1 graph/axes using ggplot2

这是数据框:

> test
             a           b          c
1   0.22904349 -0.12023869  0.1546898
2   1.09504754 -0.20398923 -0.9313251
3  -0.41200391 -0.16308791  0.6716105
4  -0.04356308 -1.81898245 -0.8074506
5  -1.23413459  1.24309479 -1.3861049
6   0.14266136 -2.22712577 -0.2341793
7  -0.25113445  0.60213281 -0.8106908
8   2.52372557  0.03794341 -1.4308955
9   0.66005867  0.74508029 -0.2922560
10  1.23552452 -0.26187445 -0.9874546

我想在一张图上绘制 a、b 和 c 的密度。我希望能够指定要按其索引绘制的列。此外,密度可以根据它们的列进行着色。这是我试过的代码:

test<- as.data.frame(cbind(a=rnorm(1:10),b=rnorm(1:10),c=rnorm(1:10)))
for(i in seq(1,ncol(test),1)){
  if(i==1)p<-ggplot(data=test, aes_string(x=names(test)[i]))
  else p<-p+ggplot(data=test, aes_string(x=names(test)[i]))
}
p+geom_density() 

我得到的错误:

Error in p + o : non-numeric argument to binary operator
In addition: Warning message:
Incompatible methods ("+.gg", "Ops.data.frame") for "+" 

请指教。谢谢

ggplot2 喜欢你的数据是长的,而不是宽的。在这种情况下,我们可以使用库tidyr(或reshape2,或reshape,或data.table

来使您的数据变宽
set.seed(1234)
test <- as.data.frame(cbind(a = rnorm(1:10), b = rnorm(1:10), c = rnorm(1:10)))
library(tidyr)

data <- gather(test, letter, value)

看看数据是如何布局的,每行一个度量。现在绘制:

library(ggplot2)
ggplot(data, aes(x = value, col = letter)) +
       geom_density()

标准的ggplot方法是使用长数据,而不是宽数据:

library(tidyr)
test_long = gather(test)

ggplot(test_long, aes(x = value, color = key)) +
    geom_density()

如果您确实需要索引,我们会将它们添加到长数据中:

test_long$index = match(test_long$key, names(test))

然后 select 要绘制的方法是对传递给 ggplot

的数据进行子集化
# if you only want columns 2 and 3 from the original data
ggplot(test_long[test_long$index %in% c(2, 3), ],
       aes(x = value, color = key)) +
    geom_density()

而且,如果你真的想要固执,你的for循环的问题是ggplot被多次调用。 ggplot() 初始化一个绘图,您不能将它多次添加到一个绘图中。你可以修复它,但你不应该这样做。

p = ggplot(data = test)

for(i in seq_along(test)) {
  if (i == 1) p = p + geom_density(aes_string(x = names(test)[i]))
  else p = p + geom_density(aes_string(x = names(test)[i]), color = "green")
}

print(p)

在这种情况下,ggplot 未按预期使用,因此您必须设置自己的颜色并添加图例将是一个真正的痛苦。这就是为什么你应该以另一种方式,简单的方式来做的部分原因。


编辑:在新的 R 会话中,这对我来说运行得很好:

# load packages
library(tidyr)
library(ggplot2)

# data from the question
test <- as.data.frame(cbind(a=rnorm(1:10),b=rnorm(1:10),c=rnorm(1:10)))

# long format
test_long = gather(test)

# plot all 3
ggplot(test_long, aes(x = value, color = key)) +
    geom_density()

# add original data indices
test_long$index = match(test_long$key, names(test))

# plot only columns 2 and 3
ggplot(test_long[test_long$index %in% c(2, 3), ],
       aes(x = value, color = key)) +
    geom_density()