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