【问题标题】:How to plot all the columns of a data frame in R如何在R中绘制数据框的所有列
【发布时间】:2011-06-20 03:02:09
【问题描述】:

数据框有 n 列,我想得到 n 个图,每列一个图。

我是新手,R语言不太流利,反正我找到了两个解决方案。

第一个有效,但它不打印列名(我需要它们!):

data <- read.csv("sample.csv",header=T,sep=",")
for ( c in data ) plot( c, type="l" )

第二个效果更好,因为它打印列名:

data <- read.csv("sample.csv",header=T,sep=",")
for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=names(data[i]),type="l")

有没有更好的(从 R 语言的角度)解决方案?

【问题讨论】:

  • 在第二个示例中,我会像这样for(i in seq_along(dat)) 初始化循环,我也不会调用我的数据data
  • 您的read.csv 可以减少到read.csv("sample.csv"),因为其他参数只是被设置为它们的默认值。

标签: r dataframe plot r-faq


【解决方案1】:

ggplot2 包需要一点学习,但结果看起来非常不错,您可以获得漂亮的图例,以及许多其他不错的功能,所有这些都无需编写太多代码。

require(ggplot2)
require(reshape2)
df <- data.frame(time = 1:10,
                 a = cumsum(rnorm(10)),
                 b = cumsum(rnorm(10)),
                 c = cumsum(rnorm(10)))
df <- melt(df ,  id.vars = 'time', variable.name = 'series')

# plot on same grid, each series colored differently -- 
# good if the series have same scale
ggplot(df, aes(time,value)) + geom_line(aes(colour = series))

# or plot on different plots
ggplot(df, aes(time,value)) + geom_line() + facet_grid(series ~ .)

【讨论】:

  • 不错的答案,但为什么你实际上需要重塑?
  • 谢谢@VerenaHaunschmid,我后来明白了:-)
  • melt需要
【解决方案2】:

有一种非常简单的方法可以使用单独的面板或同一个面板绘制数据框中的所有列:

plot.ts(data)

哪个产量(其中 X1 - X4 是列名):

查看 ?plot.ts 的所有选项。

如果您不想更好地控制绘图功能而不使用循环,您还可以执行以下操作:

par(mfcol = c(ncol(data), 1))
Map(function(x,y) plot(x, main =y), data, names(data))

【讨论】:

  • 谢谢,即使和时间序列有关,我认为它可以帮助我掌握我的数据。我喜欢单线!
  • 只是一个小提示:当添加 'plot.type=c("single")' 时,您的系列将绘制在单个图上,而不是单独的框:data &lt;- data.frame(x=c(rnorm(10)),y=c(rnorm(10)),z=c(rnorm(10))) plot.ts(data,plot.type=c("single"),lty=1:3)
  • @GeekOnAcid +1,非常感谢您提示“单身”。
  • 如果您要使用single,您还应该添加:col=rainbow(ncol(my.data)) 或类似的东西以保持行可读。
【解决方案3】:

您可以跳过障碍并将您的解决方案转换为lapplysapplyapply 调用。 (我看到@jonw 展示了一种方法。)除此之外,您已经拥有的是完全可以接受的代码。

如果这些都是时间序列或类似的,那么以下可能是一个合适的替代方案,它将每个系列在其自己的面板中绘制在单个绘图区域上。我们使用zoo 包,因为它确实可以很好地处理这样的有序数据。

require(zoo)
set.seed(1)
## example data
dat <- data.frame(X = cumsum(rnorm(100)), Y = cumsum(rnorm(100)),
                  Z = cumsum(rnorm(100)))
## convert to multivariate zoo object
datz <- zoo(dat)
## plot it
plot(datz)

这给出了:

【讨论】:

    【解决方案4】:

    我很惊讶没有人提到matplot。如果您不需要在单独的轴上绘制每条线,这非常方便。 只有一个命令:

    matplot(y = data, type = 'l', lty = 1)
    

    使用?matplot 查看所有选项。

    要添加图例,可以设置调色板然后添加:

    mypalette = rainbow(ncol(data))
    matplot(y = data, type = 'l', lty = 1, col = mypalette)
    legend(legend = colnames(data), x = "topright", y = "topright", lty = 1, lwd = 2, col = mypalette)
    

    【讨论】:

    • matlab.dark.palette 是什么,来自哪里?
    • @AlessandroJacopson 这是我经常使用的调色板功能。它来自hyperSpec 包。但是这里最好使用更知名的函数,所以我把它改成了rainbow。如果您不了解调色板功能,请查看?rainbow。很抱歉造成混淆。
    【解决方案5】:

    使用上面的一些技巧(特别感谢@daroczig 的names(df)[i] 表格),此函数打印数字变量的直方图和因子变量的条形图。探索数据框的良好开端:

    par(mfrow=c(3,3),mar=c(2,1,1,1)) #my example has 9 columns
    
    dfplot <- function(data.frame)
    {
      df <- data.frame
      ln <- length(names(data.frame))
      for(i in 1:ln){
        mname <- substitute(df[,i])
          if(is.factor(df[,i])){
            plot(df[,i],main=names(df)[i])}
            else{hist(df[,i],main=names(df)[i])}
      }
    }
    

    祝你好运,马特。

    【讨论】:

      【解决方案6】:

      lattice:

      library(lattice)
      
      df <- data.frame(time = 1:10,
                       a = cumsum(rnorm(10)),
                       b = cumsum(rnorm(10)),
                       c = cumsum(rnorm(10)))
      
      form <- as.formula(paste(paste(names(df)[- 1],  collapse = ' + '),  
                               'time',  sep = '~'))
      
      xyplot(form,  data = df,  type = 'b',  outer = TRUE)
      

      【讨论】:

        【解决方案7】:

        不幸的是,ggplot2 无法在不将数据转换为长格式的情况下(轻松地)执行此操作。您可以尝试与之抗争,但进行数据转换会更容易。这里所有的方法,包括来自 reshape2 的 melt、来自 tidyr 的 gather 和来自 tidyr 的 pivot_longerReshaping data.frame from wide to long format

        这是一个使用pivot_longer的简单示例:

        > df <- data.frame(time = 1:5, a = 1:5, b = 3:7)
        > df
          time a b
        1    1 1 3
        2    2 2 4
        3    3 3 5
        4    4 4 6
        5    5 5 7
        
        > df_wide <- df %>% pivot_longer(c(a, b), names_to = "colname", values_to = "val")
        > df_wide
        # A tibble: 10 x 3
            time colname   val
           <int> <chr>   <int>
         1     1 a           1
         2     1 b           3
         3     2 a           2
         4     2 b           4
         5     3 a           3
         6     3 b           5
         7     4 a           4
         8     4 b           6
         9     5 a           5
        10     5 b           7
        
        

        如您所见,pivot_longer 将选定的列名放入 names_to 指定的任何内容中(默认“名称”),并将长值放入 values_to 指定的任何内容中(默认“值”) .如果我对默认名称没问题,我可以使用 df %&gt;% pivot_longer(c("a", "b"))

        现在您可以正常绘图了,例如

        ggplot(df_wide, aes(x = time, y = val, color = colname)) + geom_line()
        

        【讨论】:

        • 我会将require(tidyr)require(ggplot2) 添加到您的答案中,这样它将成为一个最小的工作示例。
        • @AlessandroJacopson 我想我已经很明显这些是必需的。无论如何,如果代码中穿插着解释,MWE 有用吗?
        • 对我来说很有用,反正就是口味问题,谢谢你的回答。
        【解决方案8】:

        您可以使用main 选项指定标题(也可以通过xlabylab 指定坐标轴的标题)。例如:

        plot(data[,i], main=names(data)[i])
        

        如果您想绘制(并保存)数据帧的每个变量,您应该使用pngpdf 或您需要的任何其他图形驱动程序,然后发出dev.off() 命令。例如:

        data <- read.csv("sample.csv",header=T,sep=",")
        for (i in 1:length(data)) {
            pdf(paste('fileprefix_', names(data)[i], '.pdf', sep='')
            plot(data[,i], ylab=names(data[i]), type="l")
            dev.off()
        }
        

        或使用par()mfrow 参数将所有绘图绘制到同一图像上。例如:使用par(mfrow=c(2,2) 将接下来的 4 个图包含在同一个“图像”中。

        【讨论】:

          【解决方案9】:

          我在这台计算机上没有 R,但这里有一个破解。您可以使用par 在一个窗口中显示多个绘图,或者像这样在显示下一页之前提示单击。

          plotfun <- function(col) 
            plot(data[ , col], ylab = names(data[col]), type = "l")
          par(ask = TRUE)
          sapply(seq(1, length(data), 1), plotfun)
          

          【讨论】:

            【解决方案10】:

            如果.csv文件文件中的列名不是有效的R名:

            data <- read.csv("sample.csv",sep=";",head=TRUE)
            data2 <- read.csv("sample.csv",sep=";",head=FALSE,nrows=1)
            
            for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=data2[1,i],type="l")
            

            【讨论】:

            • 由于只使用data2的第一行,在read.csv中设置nrows = 1会更有效。
            【解决方案11】:

            这个链接对于同样的问题帮助了我很多:

            p = ggplot() + 
              geom_line(data = df_plot, aes(x = idx, y = col1), color = "blue") +
              geom_line(data = df_plot, aes(x = idx, y = col2), color = "red") 
            
            print(p)
            

            https://rpubs.com/euclid/343644

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-12-27
              • 2018-08-01
              • 2020-10-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多