Plotting Min, Max, Average in respect to Day format in R [duplicate]

The data frame has n columns and I would like to get n plots, one plot for each column.

I'm a newbie and I am not fluent in R, anyway I found two solutions.

The first one works but it does not print the column name (and I need them!):

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

The second one works better because it prints the column name:

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")

Is there any better (from the R language point of view) solutions?


Solution 1:

The ggplot2 package takes a little bit of learning, but the results look really nice, you get nice legends, plus many other nice features, all without having to write much code.

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 ~ .)

enter image description hereenter image description here

Solution 2:

There is very simple way to plot all columns from a data frame using separate panels or the same panel:

plot.ts(data)

Which yields (where X1 - X4 are column names):

enter image description here

Have look at ?plot.ts for all the options.

If you wan't more control over your plotting function and not use a loop, you could also do something like:

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

Solution 3:

You can jump through hoops and convert your solution to a lapply, sapply or apply call. (I see @jonw shows one way to do this.) Other than that what you have already is perfectly acceptable code.

If these are all a time series or similar then the following might be a suitable alternative, which plots each series in it's own panel on a single plotting region. We use the zoo package as it handles ordered data like this very well indeed.

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)

Which gives: Example of zoo plotting capabilities

Solution 4:

I'm surprised that no one mentioned matplot. It's pretty convenient in case you don't need to plot each line in separate axes. Just one command:

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

Use ?matplot to see all the options.

To add the legend, you can set color palette and then add it:

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)