使用R

时间:2019-01-15 17:31:15

标签: r loops ggplot2

我有一个包含数字和因子变量的数据集。我想用数字做一页,用因子var做另一页。首先,我用他的索引选择因子var。

我的df是IRIS数据集。

df<-iris
df$y<-sample(0:1,nrow(iris),replace=TRUE)
fact<-colnames(df)[sapply(df,is.factor)]
index_fact<-which(names(df)%in%fact)

然后我计算其余部分(数字)

nm<-ncol(df)-length(fact)

下一步是创建循环

i_F=1
i_N=1
list_plotN<- list()
list_plotF<- list()

for (i in 1:length(df)){
  plot <- ggplot(df,aes(x=df[,i],color=y,fill=y))+xlab(names(df)[i]) 

  if (is.factor(df[,i])){
    p_factor<-plot+geom_bar()
    list_plotF[[i_F]]<-p_factor
    i_F=i_F+1
  }else{
    p_numeric <- plot+geom_histogram()
    list_plotN[[i_N]]<-p_numeric
    i_N=i_N+1
  }
}

当我看到list_plotF和list_plot_N时,感觉不太好。它总是具有相同的变量。我不知道我在做什么错。

谢谢!

2 个答案:

答案 0 :(得分:1)

请考虑使用aes_string传递列名,以更好地将 x df 对齐:

for (i in 1:length(df)){
    plot <- ggplot(df, aes_string(x=names(df)[i], color="y", fill="y")) + 
              xlab(names(df)[i]) 
    ...
}

要在OP的上下文中演示使用aes()的问题和使用aes_string()的解决方案,请考虑以下具有不同数据类型列的随机数据帧:factor,char,int,num,bool,date。

数据

library(ggplot2)

set.seed(1152019)
alpha <- c(LETTERS, letters, c(0:9))
data_tools <- c("sas", "stata", "spss", "python", "r", "julia")

random_df <- data.frame(
  group = sample(data_tools, 500, replace=TRUE),
  int = as.numeric(sample(1:15, 500, replace=TRUE)),
  num = rnorm(500),
  char = replicate(500, paste(sample(LETTERS[1:2], 3, replace=TRUE), collapse="")),
  bool = as.numeric(sample(c(TRUE, FALSE), 500, replace=TRUE)),
  date = as.Date(sample(as.integer(as.Date('2019-01-01', origin='1970-01-01')):as.integer(Sys.Date()), 
                        500, replace=TRUE), origin='1970-01-01')
)

fact <- colnames(random_df)[sapply(random_df,is.factor)]
index_fact <- which(names(random_df) %in% fact)

i_F=1
i_N=1
list_plotN <- list()
list_plotF <- list()
plot <- NULL

for (i in 1:length(random_df)){
  # aes() VERSION
  #plot <- ggplot(random_df, aes(x=random_df[,i], color=group, fill=group)) +
  #  xlab(names(random_df)[i]) 

  # aes_string() VERSION
  plot <- ggplot(random_df, aes_string(x=names(random_df)[i], color="group", fill="group")) +
    xlab(names(random_df)[i]) 

  if (is.factor(random_df[,i])){
    p_factor <- plot + geom_bar()
    list_plotF[[i_F]] <- p_factor
    i_F=i_F+1
  }else{
    p_numeric <- plot + geom_histogram()
    list_plotN[[i_N]] <- p_numeric
    i_N=i_N+1
  }
}

问题 (使用aes(),其中图形输出不会根据类型改变)

Problem Plots


解决方案 (使用aes_string(),其中图形会根据类型而变化)

Solution Plots

答案 1 :(得分:1)

我不太了解您的for循环代码。但是从我看来,它似乎正在保存您制作的每个循环中的最后一个绘图。我用lapply重新构造了我认为您需要的东西。通常,我会尽量选择lapply而不是for循环。

Lapply获取值列表和一个函数,并将该函数应用于每个值。您可以像我一样单独定义函数,以便使所有内容看起来都更加简洁。然后,您只需在lapply命令中提及该功能即可。

在我们的情况下,列表是数据框df中的列的列表。首先应用的函数将创建我们的基本图。然后,它会进行快速检查,以查看所查看的列是否是一个因素。如果是一个因素,则会创建一个条形图,否则会创建一个直方图。

histOrBar <- function(var) {
  basePlot <- ggplot(df, aes_string(var))
  if ( is.factor(df[[var]]) ) {
    basePlot + geom_bar()  
  } else {
    basePlot + geom_histogram()
  }
}

loDFs <- lapply(colnames(df), histOrBar)