为什么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参数就行了。