1
votes

I am trying to make a line graph in ggplot and I am having difficulty diagnosing my error. I've read through nearly all the similar threads, but have been unable to solve my issue.

I am trying to plot Japanese CPI. I downloaded the data online from FRED.

my str looks like:

str(jpycpi)

data.frame: 179 obs. of  2 variables:
 $ DATE           : Factor w/ 179 levels "2000-04-01","2000-05-01",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ JPNCPIALLMINMEI: num  103 103 103 102 103 ...

My code to plot:

ggplot(jpycpi, aes(x=jpycpi$DATE, y=jpycpi$JPNCPIALLMINMEI)) + geom_line()

it gives me an error saying:

geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

I have tried the following and have been able to plot it, but the graph x bar is distorted for some odd reason. That code is below:

ggplot(jpycpi, aes(x=jpycpi$DATE, y=jpycpi$JPNCPIALLMINMEI, group=1)) + geom_line()
1
Does jpycpi$DATE <- as.Date(as.character(jpycpi$DATE)) fix it? If so, I can explain.zwol
it did, thank you. An explanation owuld be great. I understand why we would need to convert it to a date, but if its a factor why wouldn't we do: jpycpi$DATE <- as.Date(as.factor(jpycpi$DATE))? In other words, why as.character?Justin
as.Date(as.factor(thing which is a factor)) is the same as as.Date(thing which is a factor). I explain why an intermediate as.character may be necessary in the answer I just wrote.zwol

1 Answers

10
votes

The "Each group consists of only one observation" error message happens because your x aesthetic is a factor. ggplot takes that to mean that your independent variable is categorical, which doesn't make sense in conjunction with geom_line.

In this case, the right way to fix it is to convert that column of the data to a Date vector. ggplot understands how to use all of R's date/time classes as the x aesthetic.

Converting from a factor to a Date is a little tricky. A direct conversion,

jpycpi$DATE <- as.Date(jpycpi$DATE)

works in R version 3.3.1, but, if I remember correctly, would give nonsense results in older versions of the interpreter, because as.Date would look only at the ordinals of the factor levels, not at their labels. Instead, one should write

jpycpi$DATE <- as.Date(as.character(jpycpi$DATE))

Conversion from a factor to a character vector does look at the labels, so the subsequent conversion to a Date object will do the Right Thing.

You probably got a factor for $DATE in the first place because you used read.table or read.csv to load up the data set. The default behavior of these functions is to attempt to convert each column to a numeric vector, and failing that, to convert it to a factor. (See ?type.convert for the exact behavior.) If you're going to be importing lots of data with date columns, it's worth learning how to use the colClasses argument to read.table; this is more efficient and doesn't have gotchas like the above.