R: How to fill up missing year values in a data frame

Viewed 552

I have a quite basic R question. I have the following data frame with a year column that has no 1-year steps.

year <- c(1991,1993,1996)
value <-c(3, NA, 4)

However, for plotting a line chart, I want to fill the missing years so that I have a series from 1990 to 2000 in 1-year steps. The additional years shall be filled with NA values.

Is there a smart solution to this problem?

3 Answers

We can use complete from tidyr.

dat <- data.frame(
  year = c(1991,1993,1996),
  value = c(3, NA, 4)
)

library(dplyr)
library(tidyr)

dat2 <- dat %>%
  complete(year = 1990:2000)

print(dat2)
# # A tibble: 11 x 2
#     year value
#    <dbl> <dbl>
#  1  1990    NA
#  2  1991     3
#  3  1992    NA
#  4  1993    NA
#  5  1994    NA
#  6  1995    NA
#  7  1996     4
#  8  1997    NA
#  9  1998    NA
# 10  1999    NA
# 11  2000    NA

Using base R to generate a sequence from 1990 to 2000 and merge with original data.frame.

df1 <- data.frame(year = c(1991, 1993, 1996),
                  value = c(3, NA, 4))

merge(df1,
      data.frame(full = seq(1990, 2000))
      by.x = "year",
      by.y = "full",
      all = TRUE)

   year value
1  1990    NA
2  1991     3
3  1992    NA
4  1993    NA
5  1994    NA
6  1995    NA
7  1996     4
8  1997    NA
9  1998    NA
10 1999    NA
11 2000    NA

We assume that what you have is:

dd <- data.frame(year, value)

This is a time series so it makes sense to represent it using a time series representation such as ts, zoo or xts. We convert it to zoo and then to ts. The latter conversion will fill in the missing years.

library(zoo)
z <- read.zoo(dd)
tt <- as.ts(z)
tt
## Time Series:
## Start = 1991 
## End = 1996 
## Frequency = 1 
## [1]  3 NA NA NA NA  4

If you really want to convert it to a data frame then use fortify.zoo(tt) .

Plotting

If the only reason to do this is for plotting a line chart then alternately just remove the missing values. Any of these will work.

plot(na.omit(dd), type = "l", xlab = "year", ylab = "value")

plot(na.omit(z), xlab = "year", ylab = "value")

library(ggplot2)
autoplot(na.omit(z)) + xlab("year") + ylab("value")

The last plot is shown here:

screnshot

Related