Spaniel
Spaniel

Reputation: 367

Function to generate multiple ggplots from dataframe fails

I know there is a similar question that has been asked, but in that case plots are generated with one variable being used for each plot. Here, I am trying to get various variables to each be plotted individually against the variable Year in a dataframe.

The function aims to: produce a line chart by plotting the specified year variable against every other column in the dataframe, indicated by the index range of the rest of the columns. For example if the first variable is year, the index range of the leftover columns is (df[2:5]), so the range 2:5 is put as an argument into the function in place of cRange. Also, NAs of the respective variable are filtered out and the plots are saved.

Please help!

The function:

graphGenerator<- function(df, year, cRange){ 
  graphList <- list()
  for(i in seq_along(cRange)){
  graphList[[i]] = ggplot(data=subset(df, !is.na(df[i]))) + 
      geom_line(aes(year, !!as.name(names(df)[i])))
  ggsave(paste0(names(df)[i], ".png"))
  graphList
  }}

The data:

ecoData <- structure(list(Year = c(1960, 1961, 1962, 1963, 1964, 1965, 1966, 
1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 
1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 
1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996), RealEffectiveExchangeRateIndex = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, 89.1269387127116, 83.9779175497827, 83.7956315182616, 
73.5014785270752, 75.7044676101763, 77.114476045285, 82.102672177161, 
85.3965937406861, 89.1012840379478, 94.3997472738225, 100.791169630373, 
101.56567859291, 101.160611256909, 90.1771445956206, 85.9945035312609, 
87.4781798613309, 89.3091576923388), OfficialExchangeRateLCU = c(60.000000059, 
60.000000059, 60.000000059, 60.000000059, 60.000000059, 60.000000059, 
60.000000059, 61.6666667275, 70.00000007, 70.00000007, 70.00000007, 
69.4686667071667, 64.2714166659167, 58.2600833323333, 57.686499999, 
57.4069166656667, 66.9029166660833, 75.9618333324167, 76.6678333328333, 
67.1249999995833, 71.7019166659167, 92.3218333325, 109.859166665833, 
143.429916666333, 160.760999999667, 170.044083333167, 140.048375442168, 
123.478333333333, 116.486833333333, 118.377666666667, 101.933916666667, 
103.911583333333, 102.379083333333, 127.260416666667, 133.957955, 
124.689, 126.661583333333), ServiceExportsBoPcurrentUSDollar = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 5434092162.01586, 
5105474372.63073, 6151894275.996, 8195300861.29035, 10285107409.6294, 
11593348447.5048, 11330920901.9377, 11541515968.9387, 11365066188.3115, 
12338801111.8165, 12723146517.332, 17835669125.0581, 21705339605.8585, 
24456612401.8389, 24617674457.06, 27936975048.684, 29170874541.9182, 
33490003618.7196, 30449125666.4456, 33815815244.8677, 40419916876.5791, 
44082589444.757), GoodsExportsBoPcurrent.USDollar = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 7821050191.67188, 
9015180711.17643, 10600891398.1145, 13491229192.842, 18356978259.2883, 
20546771286.8606, 20973667222.4509, 21288329911.1421, 20004108399.523, 
22964530676.3909, 23959552537.1693, 26875768096.4645, 33861409837.0844, 
39945426891.8287, 43783030149.9251, 55657617113.9207, 60166814752.7761, 
65847035600.8744, 62018683095.783, 73968443401.3603, 93490417576.2292, 
103236926608.264)), row.names = c(NA, -37L), class = "data.frame")

Using the function with the data:

library(tidyverse)
graphs <- graphGenerator(ecoData, ecoData$Year, 2:ncol(ecoData))

Upvotes: 0

Views: 59

Answers (1)

The main problem with your function is that you were introducing all the "ecoData$Year" vector as the x axis values; while, inside the function you were subsetting the y axis values for each variable. Therefore, the error implied that the vector for the x axis had different length from the y axis vector. I made some few modifications to your function so it no longer shows the error and produces the desired plots.

graphGenerator<- function(df, cRange){ 
  graphList <- list()
  #Modified the range to be exactly the range of the columns
  for(i in cRange){
    #Modified the subset function to do it according to the i column
    graphList[[i]] = ggplot(data=subset(df, !is.na(df[,i])),
                            aes(x = Year, 
                                y = !!as.name(names(df)[i]))) + 
      geom_line()
    ggsave(paste0(names(df)[i], ".png"))
    graphList
  }}

Upvotes: 3

Related Questions