R 使用ggplot2在1个图形/轴上绘制对应于多个列(由索引指定)的多个绘图

R 使用ggplot2在1个图形/轴上绘制对应于多个列(由索引指定)的多个绘图,r,indexing,plot,ggplot2,density-plot,R,Indexing,Plot,Ggplot2,Density Plot,以下是数据框: > 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

以下是数据框:

> 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() 

请给我一些建议。谢谢

ggplot2希望您的数据是长的,而不是宽的。在这种情况下,我们可以通过使用库tidyr或REGRAPE2、REGRAPE或data.table来扩大数据范围


标准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))
然后,选择要绘制哪些图形的方法是将传递给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()

按索引指定它们真的是一个优先事项吗?似乎你认为你需要这样做,因为你认为你需要一个for循环,但事实并非如此。如果有很多列,索引将使命名列变得更容易。上面的数据框只是一个例子。嗨,Gregor,很抱歉回复晚了。安装tidyr时遇到一些问题,当时很忙,但现在一切正常。第一组代码运行良好。但是,我在使用第二组代码时遇到了问题,这组代码用于第2列和第3列。我收到以下错误:existsname中的错误,envir=env,mode=mode:缺少参数env,没有默认值。在第三个代码块中尝试绘图之前,是否运行了第二个代码块?如果您没有运行测试,您将得到这个错误。\u long$index=match。。。行。我确实运行了测试\u long$index=match。。。行,并已再次检查。错误仍然存在。它在新的R会话中对我有效。我把我运行的全部代码放在问题的底部;它与上面的代码没有什么不同。在新的R会话中尝试它,如果它不起作用,也许可以确保您的软件包是最新的?更新后尝试它,不知怎的,它现在起作用了。谢谢
# 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()
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)
# 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()