R优质资源RR

为什么for循环和aes八字不合

2020-04-17  本文已影响0人  小洁忘了怎么分身

前面写过这篇:批量绘制箱线图https://www.jianshu.com/p/ec9034fe9a2c
今天发现了新问题。是aes和for循环的八字不合的诡异现象,来分析一下大家看看,能不能破:

1.示例数据

mat <- matrix(rnorm(60),nrow=10)
colnames(mat)=paste0('sample',1:6)
rownames(mat)=paste0('gene',1:10)
library(ggplot2)
mat2 <- t(mat)
mat2 <- data.frame(mat2) 
mat2$group=rep(c('A','B'),each=3)

mat2长这样:


我们的目的是对对每一个基因画箱线图,这可以通过gather+分面或者for循环+aes_string来实现,这个没有问题。

尝试1:当不用for循环的时候

p1 = ggplot(data=mat2)+
  geom_boxplot(aes(x=group,y=mat2[,1],color = group))
p2 = ggplot(data=mat2)+
  geom_boxplot(aes(x=group,y=mat2[,2],color = group))
library(patchwork)
p1+p2

成功了。

尝试2:把1和2替换成i,传参试试

i=1
p1 = ggplot(data=mat2)+
  geom_boxplot(aes(x=group,y=mat2[,i],color = group))
i=2
p2 = ggplot(data=mat2)+
  geom_boxplot(aes(x=group,y=mat2[,i],color = group))
library(patchwork)
p1+p2

所以放进for循环也是一样的,会出10张一样的图

p=list()
for(i in 1:10){
  p[[i]]=ggplot(data=mat2)+
    geom_boxplot(aes(x=group,y=mat2[,i],color = group))
}
wrap_plots(p,nrow=2,guides = 'collect')

所有图都一样,所以失败了。

尝试3:换apply试试呢?

p = apply(mat2[,1:10], 2, function(i){
  ggplot(data=mat2)+
    geom_boxplot(aes(x=group,y=i,color = group))
})
wrap_plots(p,nrow=2,guides = 'collect')

所以你说,aes它不能传参吗?是不能,大佬们说需要传参就改成aes_string,它确实可以。但我好奇是为什么apply就能做出来。可能是因为它的循环方式和for循环不一样?

把这个apply的循环方式原样替换到for循环里,仍然是不行的:

p = list()
n = 0
for(i in mat2[,1:10]){
  n = n+1
  p[[n]]=ggplot(data=mat2)+
    geom_boxplot(aes(x=group,y=i,color = group))
}
wrap_plots(p,nrow=2,guides = 'collect')

经过这样的尝试,我觉得问题应该在于aes传参数有一点问题。for循环涉及到每次y映射的改变,所以就不行。

But,如果我非要用for循环实现呢?

什么叫倔强,可能我撞了南墙才会回头吧,可能我见了黄河才会死心吧~aaa,想用,那就是有办法的。实在不行,我们每次改完数据再作图就好了!

一个知识点,当gene这一列不存在于mat2的时候,mat2$gene = i表示新增一列,列名为gene,内容为i。当gene这一列存在于mat2的时候,mat2$gene = i表示修改gene这一列的内容,改为i。

p = list()
n = 0
for(i in mat2[,1:10]){
  n = n+1
  mat2$gene = i
  p[[n]]=ggplot(data=mat2)+
    geom_boxplot(aes(x=group,y=gene,color = group))
}
wrap_plots(p,nrow=2,guides = 'collect')

一个意义不大的问题引起了我的兴趣,两个小时又木有了。没办法,谁叫我对R语言兴趣至深,爱得深沉 哈哈。

当你即将放弃,其实彼岸已经在眼前

小郭发来aes帮助文档里的一段例子:



我们都在惊叹,两个叹号是什么操作???

p=list()
for(i in 1:10) {
  p[[i]] = ggplot(data = df, aes(x = group, y = !!df[, i])) +
    geom_boxplot(aes(color = group))
}
library(patchwork)
wrap_plots(p, nrow = 2, guides = 'collect')

问题就这么解决了!你说诡异不诡异。ggplot2博大精深,大佬们玩的很深沉,表示十分佩服。
ps:你会看到每种方法出来的列名都是不一样的,但那个可以改,加个labels参数就行了。

上一篇下一篇

猜你喜欢

热点阅读