【问题标题】:Loop through and plot columns of two identical dataframes循环并绘制两个相同数据框的列
【发布时间】:2018-05-28 18:57:00
【问题描述】:

我有两个数据框要相互对照:

> df1 <- data.frame(HV = c(3,3,3), NAtlantic850t = c(0.501, 1.373, 1.88), AO = c(-0.0512, 0.2892, 0.0664))

> df2 <- data.frame(HV = c(3,3,2), NAtlantic850t = c(1.2384, 1.3637, -0.0332), AO = c(-0.5915, -0.0596, -0.8842))

它们是相同的,我想将它们绘制成列与列(例如 df1$HV、df2$HV) - 循环遍历数据框列并在散点图中将它们相互绘制。

我已经查看了 20 多个类似问题的问题,但无法弄清楚 - 希望从哪里开始提供一些帮助。当它们是两个 DF 时,我可以使用 lapply 和 plot 或 ggplot 吗?我应该先合并它们吗?

【问题讨论】:

  • 不可见(地图(绘图,df1,df2))

标签: r plot ggplot2 apply


【解决方案1】:

正如你所建议的,在调用 plot 命令之前,我确实会首先重新排列成一个可绘制数据框的列表。如果您想将data 参数输入ggplot,我认为这尤其适用。比如:

plot_dfs <- lapply(names(df1),function(nm)data.frame(col1 = df1[,nm], col2 = df2[,nm]))
for (df in plot_dfs)plot(x = df[,"col1"], y = df[,"col2"])

或使用ggplot:

for (df in plot_dfs){
  print(
  ggplot(data = df, aes(x=col1, y=col2)) +
  geom_point())}

如果你想将列名添加为绘图标题,你可以这样做:

for (idx in seq_along(plot_dfs)){
  print(
    ggplot(data = plot_dfs[[idx]], aes(x=col1, y=col2)) +
      ggtitle(names(df1)[idx]) +
      geom_point())}

【讨论】:

  • 太棒了,有没有办法保留列名,这样当我绘制它们时它不只是绘制(col1,col2)?我想它必须在 lapply 调用中 - 使用 setNames()?
  • 如果您要从两个 dfs 中保留相同(相同)的 colnames,这意味着您必须制作一个具有相同 colnames 的 df(不可能)和一个具有相同轴标签的图(不提供信息) .最好将匹配的 colname 添加为绘图标题,然后将轴标记为 value_df1 和 value_df2 之类的东西。我已经添加了上面的代码。
  • 绝对 - 这就是我们想要的,谢谢。对于面板图,分面是否会在循环中起作用?我尝试添加 facet_wrap(~plot_dfs[[idx]]) 但它不喜欢列表对象
  • 对于分面,您需要将所有内容组合到一个 df 中,在其中添加一个变量,说明您从哪一列添加了数据,这样您就可以围绕该变量进行分面。如果你想安排一个情节列表(就像你现在可以生成的那样),你可以看看 ggarrange。
【解决方案2】:

您可以像这样遍历列:

for(col in 1:ncol(df1)){
  plot(df1[,col], df2[,col])
}

在运行此之前,请确保两个数据框具有相同的列数(并且列的顺序相同)。

【讨论】:

    【解决方案3】:

    这是一种方法——遍历列索引并一个一个地创建图,将它们添加到列表中并将每个图写入文件:

    library(ggplot2)
    
    # create some data to plot 
    df1 <- iris[, sapply(iris, is.numeric)]
    df2 <- iris[sample(1:nrow(iris)), sapply(iris, is.numeric)]
    
    # a list to catch each plot object 
    plot_list <- vector(mode="list", length=ncol(df1))
    
    for (idx in seq_along(df1)){
    
      plot_list[[idx]] <- ggplot2::qplot(df1[[idx]], df2[[idx]]) + 
        labs(title=names(df1)[idx])
    
      ggsave(filename=paste0(names(df1)[idx], ".pdf"), plot=plot_list[[idx]])
    }
    

    正如您在问题中所建议的,您还可以将s/lapply() 与匿名函数一起使用,例如像这样(虽然这里我们没有存储图,只是将每个图写入磁盘):

    lapply(seq_along(df1), function(idx){
      the_plot <- ggplot2::qplot(df1[[id]], df2[[idx]]) + labs(title=names(df1)[idx])
      ggsave(filename=paste0(names(df1)[idx], ".pdf"), plot=the_plot)
    })
    

    如果您想保留绘图列表(如 for-loop 示例中所示),只需将 lapply() 分配给变量(例如 plot_list)并在关闭函数之前添加类似 return(the_plot) 的行.

    您可以通过多种方式修改/调整此方法,具体取决于您的目标。

    希望对你有所帮助~~

    p.s. 如果列的顺序可能不同,最好循环遍历列 names 而不是列索引(即使用 for (colname in names(df1)){...而不是for (idx in seq_along(df1)){...)。您可以对名称和索引使用相同的 [[ 子集语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 2021-11-10
      • 2018-03-16
      • 2017-06-24
      相关资源
      最近更新 更多