遍历数据框的列以使用ggplot2创建图表

3

我正在努力克服这个问题。无法进一步。

我有一个包含因子和数值变量的数据框。以下显示了前几行和列。

# A tibble: 6 x 5
  cluster SEV_D SEV_M   OBS   PAN  
    <int> <dbl> <dbl> <fct> <fct>  
1       1     5     1    0     1    
2       2     6     1    0     0    
3       1     5     1    0     1    
4       2     4     2    0     0    
5       1     4     1    1     1    
6       1     4     2    1     0   

cluster=as.factor(c(1,2,1,2,1,1))  
SEV_D=as.numeric(c(5,6,5,4,4,4))
SEV_M=as.numeric(c(1,1,1,2,1,2))
OBS=as.factor(c(0,0,0,0,1,1))
PAN=as.factor(c(1,0,1,0,1,0))
data<-data.frame(cluster,SEV_D,SEV_M,OBS,PAN) 

我将数据框按照数值和因子变量进行划分,保留“cluster”在两个子集中,因为我需要它进行分组。

data_fact <- data[, sapply(data, class) == 'factor']

data_cont <- data[, sapply(data, class) == 'numeric' | names(data) 
== "cluster"]

以下两段代码会产生我想要的图形。
data_fact %>% group_by(cluster,OBS)%>%summarise(total.count=n()) %>% 
ggplot(., aes(x=cluster, y=total.count, fill=OBS)) + 
geom_bar(position = 'dodge', stat='identity') + 
geom_text(aes(label=total.count),  
position=position_dodge(width=0.9), vjust=-0.2)

data_cont %>% group_by(cluster) %>% dplyr::summarise(mean = 
mean(SEV_D), sd = sd(SEV_D)) %>% 
ggplot(.,aes(x=cluster,y=mean))+geom_bar(position=position_dodge(), 
stat="identity",colour="black",size=.3)+geom_errorbar(aes(ymin=mean- 
sd, ymax=mean+sd),size=.3,width=.4,position=position_dodge(.4)) + 
ggtitle("SEV_D")

我的目标是在数据框中循环遍历列,创建与变量数量相同的图表,并将这些图表存储在单个表格中。

我尝试的方法是

col<-names(data_fact)[!names(data_fact)%in%"cluster"]

for(i in col) {
data_fact %>% group_by(cluster,i)%>%summarise(total.count=n()) %>% 
ggplot(., aes(x=cluster, y=total.count, fill=i)) + geom_bar(position 
= 'dodge', stat='identity') + geom_text(aes(label=total.count), 
position=position_dodge(width=0.9), vjust=-0.2)
}

但它会抛出以下错误:

在 grouped_df_impl(data, unname(vars), drop) 中有错误: 列 i 是未知的

除此之外,我担心这段代码不能在一个表格中显示所有图表。任何帮助将不胜感激!!!


你可以在循环的开头尝试类似于 data_fact$grouping_col <- data_fact[[i]] 的语句,然后在 group_by 中使用 grouping_col 而不是 i。你没有一个名为 i 的列,这就是循环失败的原因。 - Joseph Clark McIntyre
你遇到的问题是由于dplyr和ggplot中的非标准评估(NSE)引起的。您可以在此处找到易于阅读的NSE简介:https://dplyr.tidyverse.org/articles/programming.html。 - A. Stam
1个回答

3
上面的链接是一个很好的参考。或者查看Rstudio的tidyeval cheatsheet:https://github.com/rstudio/cheatsheets/raw/master/tidyeval.pdf 要在ggplot语句中评估i,您需要使用!!ensym( )函数构造解除引用字符串。此外,您需要使用print语句在循环内打印图形。
library(ggplot2)

col<-names(data_fact)[!names(data_fact)%in%"cluster"]

for(i in col) {
   print(i)

   g<-data_fact %>% group_by(cluster, !!ensym(i)) %>% summarise(total.count=n()) %>% 
     ggplot(., aes(x=cluster, y=total.count, fill=!!ensym(i))) + 
     geom_bar(position  = 'dodge', stat='identity') + 
     geom_text(aes(label=total.count), position = position_dodge(width=0.9), vjust=-0.2) +
     labs(title=i)
  print(g)
}

现在的分组不再产生相同的输出,因此绘图也随之变化。 [1] "PAN" # A tibble: 2 x 3 # Groups: cluster [?] cluster "PAN" total.count <fct> <chr> <int> 1 1 PAN 720 2 2 PAN 167 应该是 # A tibble: 4 x 3 # Groups: cluster [?] cluster PAN total.count <fct> <fct> <int> 1 1 0 648 2 1 1 72 3 2 0 133 4 2 1 34 - FcmC
1
@FilippoCorponi,抱歉我的错误,请看更正,我需要的是rlang包中的!!ensym()而不仅仅是!! - Dave2e

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接