I am a newbie in R. Could somebody please help me with this problem? I want to store the loop table data and export it into excel file, but I have not succeeded. Thanks.
Qquest7 <- c("A", "B", "A", "A", "A", "B", "B", "B", "B", "A")
Qquest24 <- c("neutral", "somewhat satisfied", "somewhat satisfied", "not able to rate", "somewhat satisfied", "less satisfied", "not able to rate", "dissatisfied", "very satisfied", "dissatisfied")
Qquest25 <- c("not able to rate", "not able to rate", "not able to rate", "somewhat satisfied", "not able to rate", "not able to rate", "dissatisfied", "dissatisfied", "not able to rate", "very satisfied")
Qquest26 <- c("not able to rate", "somewhat satisfied", "not able to rate", "less satisfied", "not able to rate", "neutral", "somewhat satisfied", "neutral", "neutral", "somewhat satisfied")
Qquest27 <- c("very satisfied", "not able to rate", "somewhat satisfied", "neutral", "very satisfied", "neutral", "neutral", "somewhat satisfied", "neutral", "not able to rate")
Qquest28 <- c("not able to rate", "not able to rate", "not able to rate", "not able to rate", "not able to rate", "not able to rate", "very satisfied", "neutral", "somewhat satisfied", "neutral")
Qquest29 <- c("desktop", "laptop", "tablet", "cellphone", "desktop", "desktop", "tablet", "laptop", "cellphone", "laptop")
df <- data.frame(Qquest7, Qquest24, Qquest25, Qquest26, Qquest27, Qquest28, Qquest29)
library(openxlsx)
trial2429 <- c("Qquest24","Qquest25", "Qquest26", "Qquest27", "Qquest28", "Qquest29")
x <- data.frame()
y <- data.frame()
for (i in df[trial2429]){
x[i] <- table(df$Qquest7, i)
y <- print(x)
}
write.xlsx(y, file = "trial2429.xlsx")
I'm not 100% what you're after as desired output, but this function I've used for my own purposes might do the trick for you. Using your df and trial2429 for data, first give trial2429 some names:
names(trial2429) <- trial2429
Now, build a function that takes a list and sequentially adds its contents to a .csv file:
## Export list
export_results <- function(df_list, file_name = "outfile.csv") {
if (file.exists(file_name)) {
file.remove(file_name)
print("Removed old file.")
}
## Clean export function
writeout <- function(table_name) {
write(table_name, file_name, sep = ",", append = TRUE)
tab.out <- df_list[[table_name]]
tab.out <- cbind(rownames(tab.out), tab.out)
write.table(
tab.out,
file_name,
row.names = FALSE,
sep = ",",
append = TRUE
)
write("", file_name, sep = ",", append = TRUE)
}
for (i in names(df_list)) {
writeout(i)
}
}
Get the table version for each question that you're after, and store it in a list:
q.list <- lapply(trial2429, function(x){
table(df$Qquest7, df[[x]])
})
Call the function defined above on that list:
export_results(q.list, file_name = "trial2429.csv")
It'll throw some warning messages, but it seems to not cause any problems- your output should like this in Excel:
Edit: Fixed number-of-columns issue
Related
I'm new to R and trying to get this data in a 100% Stacked Bar chart in R to look like this
The data looks like this
ccEFFECT <- data$Q7_1
ccEFFECT [ccEFFECT == -99] <- NA
ccEFFECTS<- factor(ccEFFECT , labels = c("Strongly Disagree", "Disagree", "Neither Agree nor Disagree", "Agree", "Strongly Agree"))
levels(ccEFFECTS )
str(ccEFFECTS )
summary (ccEFFECTS )
length(na.omit(ccEFFECTS ))
length(ccEFFECTS )
ccEFFECTfrequency <- table (ccEFFECTS ) #frequency
ccEFFECTfrequency
#percentages
ccEFFECT_PERCENTAGE=prop.table(table(ccEFFECTS)) * 100
ccEFFECT_PERCENTAGE
barplot(ccEFFECT_PERCENTAGE)
Q2EFFECT<- data$Q7_2
Q2EFFECT [Q2EFFECT == -99] <- NA
Q2EFFECTS<- factor(Q2EFFECT , labels = c("Strongly Disagree", "Disagree", "Neither Agree nor Disagree", "Agree", "Strongly Agree"))
levels(Q2EFFECTS )# how many levels of a categorical variable
str(Q2EFFECTS )
summary (Q2EFFECTS )
length(na.omit(Q2EFFECTS ))
length(Q2EFFECTS )
Q2EFFECTfrequency <- table (Q2EFFECTS ) #frequency
Q2EFFECTfrequency
#percentages
Q2EFFECT_PERCENTAGE=prop.table(table(Q2EFFECTS)) * 100
Q2EFFECT_PERCENTAGE
barplot(Q2EFFECT_PERCENTAGE)
Any suggestions.
Let dummy is data you give as picture. Then,
dummy <- dummy %>% filter(Q71 != -99)
colnames(dummy) <- c("concern about home price", "concern about jobs", "concern about unemployment","concern about importation", "concern about inflation")
dummy %>%
reshape2::melt(value.name = "response",
measure.var = c("concern about home price",
"concern about jobs",
"concern about unemployment",
"concern about importation",
"concern about inflation")) %>%
group_by(variable, response) %>%
summarise(n = n()/ 29) %>%
ungroup %>%
mutate(response = factor(response, labels = c("Strongly Disagree", "Disagree", "Neither Agree nor Disagree", "Agree", "Strongly Agree"), ordered = T)) %>%
ggplot(aes(fill = response, y = n, x = variable)) +
geom_bar(position = "fill", stat = "identity", width = 0.2) +
coord_flip() + scale_fill_manual(values = c("steelblue", "yellow", "grey", "orange", "darkblue")) +
theme_minimal()
result is like
I am new to using R, and I am trying to make a diverging stacked bar chart, as demonstrated here and here.
I have the following R code that I modified from working code. My modified code is giving me an error. The error I am getting is Error: id variables not found in data: Item . I do not understand why I'm getting this error.
library("devtools")
library("likert")
scale_height = knitr::opts_chunk$get('fig.height')*0.5
scale_width = knitr::opts_chunk$get('fig.width')*1.25
knitr::opts_chunk$set(fig.height = scale_height, fig.width = scale_width)
theme_update(legend.text = element_text(size = rel(0.7)))
# u = understandability
title_u = "Understandability"
headers_u_n_a = c("Type", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree")
y_label = "Video Transformation"
understandability_csv_text = "Type Strongly Disagree Disagree Neutral Agree Strongly Agree
WT 0.00 0.00 0.00 27.27 72.73
WoT 0.00 18.18 18.18 18.18 45.45
TF 9.09 9.09 36.36 27.27 18.18"
u_data = read.csv(text=understandability_csv_text, header=TRUE, sep="\t")
u_data$Type = as.factor(u_data$Type)
names(u_data) = headers_u_n_a
u_data_summary = likert(summary = u_data)
plot(u_data_summary, plot.percent.neutral=TRUE, plot.percent.low=FALSE, plot.percent.high=FALSE) + ylab(y_label) + ggtitle(title_u)
I was modifying this following MWE:
library("devtools")
library("likert")
scale_height = knitr::opts_chunk$get('fig.height')*0.5
scale_width = knitr::opts_chunk$get('fig.width')*1.25
knitr::opts_chunk$set(fig.height = scale_height, fig.width = scale_width)
theme_update(legend.text = element_text(size = rel(3)))
theme_update(axis.title = element_text(size = rel(4)))
theme_update(plot.title = element_text(size = rel(4)))
theme_update(axis.text = element_text(size = rel(4)))
title_q1 = "I'm satisfied with the way the results are ranked"
headers_q1 = c("Item","Strongly Disagree", "Disagree", "Neither Agree nor Disagree", "Agree", "Strongly Agree")
xlab_first = "Position"
CSV_Text = "K,Strongly Disagree,Disagree,Neither Agree nor Disagree,Agree,Strongly Agree
10,2.752293578,15.59633028,18.34862385,48.62385321,14.67889908
5,1.739130435,5.217391304,6.086956522,48.69565217,38.26086957
1,1.639344262,0,0,13.93442623,84.42622951
20,11.76470588,33.33333333,22.54901961,27.45098039,4.901960784"
first_q1 = read.csv(text=CSV_Text, header=TRUE, sep=",")
first_q1$K= as.factor(first_q1$K)
names(first_q1) = headers_q1
s_first_q1 = likert(summary = first_q1)
plot(s_first_q1, plot.percent.neutral=FALSE, plot.percent.low=FALSE, plot.percent.high=FALSE) + xlab(xlab_first) + ggtitle(title_q1)
I was able to fix it and get it working by changing
headers_u_n_a = c("Type", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree")
to
headers_u_n_a = c("Item", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree")
However, I am still unsure why this was needed.
Im trying to create a new variable, recode it, turn it into a factor variable with new labels. First part of the recode goes OK, but when I try to convert to factor variable it gives me this message: Error in unique.default(x, nmax = nmax) : unique() applies only to vectors
mutate(locale = case_when (V4024 %in% c("R/hme-own dwell",
"R/hme-det bldg","R/home-vac/2nd",
"R/hme-htl/mtl") ~ 1,
V4024 %in% c("N/hme-own yrd", "N/hme apt hall",
"N/hme-on street") ~ 2,
V4024 %in% c("Frn/hme-yard etc","Frn/hme-on str",
"Frn/hme-at hme", "Frn/hme-apt hall"
) ~ 3,
V4024 %in% c("Comm-rest/bar","Other comm bld",
"Gas station", "Office", "Bank",
"Factory/warehouse") ~ 4,
V4024 %in% c("Park-apt etc",
"Park-parking etc") ~ 5,
V4024 %in% c("Schl-school bldg",
"Schl-school prop") ~ 6,
V4024 %in% c("Park-noncomm","Open-on street",
"Open-pub transp",
"Open-apt yd etc") ~ 7,
V4024 %in% c("Other-other") ~ 8))
mutate (locale = as.factor(locale)) %>%
mutate(locale = fct_recode(as.factor(locale),
"Victim's Home" = "1", "Near Victim's Home" = "2",
"At or Near friends/acq" = "3",
"Commercial Place" = "4",
"Parking lot/Garage" = "5",
"School" = "6", "Open Areas/Public Transport" = "7",
"Other" = "8"))
Not exactly sure why the error occurs but I think you are taking a long route to achieve your desired output. Why not assign relevant fct_recode output in case_when directly?
library(dplyr)
mutate(locale = factor(case_when (V4024 %in% c("R/hme-own dwell",
"R/hme-det bldg","R/home-vac/2nd",
"R/hme-htl/mtl") ~ "Victim's Home",
V4024 %in% c("N/hme-own yrd", "N/hme apt hall",
"N/hme-on street") ~ "Near Victim's Home",
V4024 %in% c("Frn/hme-yard etc","Frn/hme-on str",
"Frn/hme-at hme", "Frn/hme-apt hall"
) ~ "At or Near friends/acq",
V4024 %in% c("Comm-rest/bar","Other comm bld",
"Gas station", "Office", "Bank",
"Factory/warehouse") ~ "Commercial Place",
V4024 %in% c("Park-apt etc",
"Park-parking etc") ~ "Parking lot/Garage",
V4024 %in% c("Schl-school bldg",
"Schl-school prop") ~ "School",
V4024 %in% c("Park-noncomm","Open-on street",
"Open-pub transp",
"Open-apt yd etc") ~ "Open Areas/Public Transport",
V4024 %in% c("Other-other") ~ "Other")))
I've created some charts using the Likert package, however when I create plots by groups the plot.percents = TRUE won't give me the labels for each response category. The plot.percents.high =TRUE and plot.percents.low = TRUE gives me the combined percentage, however I want it for all of the response categories. It works fine with the ungrouped data. The code I`m using is:
Make some data
library(likert)
library (reshape)
Group <- c("Group 1", "Group 1", "Group 1", "Group 1", "Group 1", "Group 1", "Group 1", "Group 2", "Group 2", "Group 2", "Group 2", "Group 2",
"Group 2","Group 2", "Group 3", "Group 3", "Group 3", "Group 3","Group 3","Group 3","Group 3")
Var1 <- c("Agree", "Agree", "Strongly agree", "Agree", "Strongly disagree", "Agree","Strongly agree", "Disagree", "Strongly agree",
"Strongly agree", "Agree", "Disagree", "Agree", "Strongly disagree", "Agree", "Agree", "Agree", "Disagree", "Strongly agree",
"Strongly disagree", "Strongly agree")
df <- as.data.frame (cbind(Group, Var1))
Variable <- c("Var1")
df2 <- (df[Variable])
likert.df <- likert (df2)
likert.df.group <- likert (df2, grouping=df$Group)
likert.df is the responses for all, likert.df.group is the responses for each group. When I run the plot (below) with just likert.df, I get the percentages for each response, when I run it for likert.df.group, they disappear.
likert.bar.plot(likert.df, low.color = "#007CC2",
high.color = "#F7971C", neutral.color = "grey90",
neutral.color.ramp = "white", plot.percent.low = FALSE,
plot.percent.high = FALSE, plot.percent.neutral = FALSE,
plot.percents = TRUE, text.size = 4,
text.color = "black", centered = FALSE,
include.center = FALSE, ordered = FALSE,
wrap.grouping = 50, legend = "Response",
legend.position = "bottom", panel.arrange = "v",
panel.strip.color = "grey90")+
ggtitle("Chart Title") +
theme (panel.background = element_rect(fill="NA")) +
theme (axis.text.y = element_text (colour="black", size="10", hjust=0))+
theme (axis.text.x = element_text (colour="black", size="10")) +
theme (legend.title = element_blank())+
theme (plot.margin = unit (c(0,0,0,0),"mm"))
Am I missing something?
According to the function source, printing of plot.percents is not currently supported for grouped analysis. See https://github.com/jbryer/likert/blob/master/R/plot.likert.bar.r#L174
There's a slight problem with the package code, which is easy to fix (unless I am overlooking something else).
On line 175 https://github.com/jbryer/likert/blob/master/R/plot.likert.bar.r#L175 change:
# lpercentpos <- ddply(results[results$value > 0,], .(Item), transform,
lpercentpos <- ddply(results[results$value > 0,], .(Group, Item), transform,
on line 177 https://github.com/jbryer/likert/blob/master/R/plot.likert.bar.r#L177 change:
# p + geom_text(data=lpercentpos, aes(x=Group, y=pos, label=paste0(round(value), '%'),
p <- p + geom_text(data=lpercentpos, aes(x=Group, y=pos, label=paste0(round(value), '%'),
and on line 184 https://github.com/jbryer/likert/blob/master/R/plot.likert.bar.r#L184 change:
# lpercentneg <- ddply(lpercentneg, .(Item), transform,
lpercentneg <- ddply(lpercentneg, .(Group, Item), transform,
Then uncomment this section and remove FALSE from the if statement
# if(FALSE & plot.percents) { #TODO: implement for grouping
if(plot.percents) {
Here's the snippet which goes inside the if statement:
# if(FALSE & plot.percents) { #TODO: implement for grouping
if(plot.percents) {
# warning('plot.percents is not currenlty supported for grouped analysis.')
lpercentpos <- ddply(results[results$value > 0,], .(Group, Item), transform,
pos = cumsum(value) - 0.5*value)
p <- p + geom_text(data=lpercentpos, aes(x=Group, y=pos, label=paste0(round(value), '%'),
group=Item), size=text.size)
lpercentneg <- results[results$value < 0,]
if(nrow(lpercentneg) > 0) {
lpercentneg <- lpercentneg[nrow(lpercentneg):1,]
lpercentneg$value <- abs(lpercentneg$value)
lpercentneg <- ddply(lpercentneg, .(Group, Item), transform,
pos = cumsum(value) - 0.5*value)
lpercentneg$pos <- lpercentneg$pos * -1
p <- p + geom_text(data=lpercentneg, aes(x=Item, y=pos, label=paste0(round(abs(value)), '%')),
size=text.size)
}
}
I haven't done much testing, but your test data works fine and produces this output:
I fixed this issue and submitted a pull request to Jason. In the meantime you can pull the changes from here: https://github.com/aseidlitz/likert
I wrote a little add-on based off the source code, if you don't want to bother modding the source material. Just takes the answer above and applies it. Shouldn't be too hard to put into a user function if you make a lot of graphs with it. I have been doing some work trying to get the percents added and then figure a way to add the N's somewhere on the graph.
library(likert)
library(reshape)
library(plyr)
#--------------- Works using likert package, problems with the modded source code)
rm(list=ls(all=T))
# ---------------- Example Data -------------------- #
likert.responses <- c("Agree", "Neutral", "Strongly agree", "Disagree", "Strongly disagree", NA)
questions <- c("Q_1","Q_2","Q_3")
groupA <- c("White", "Afr. American", "Hispanic", "Other")
set.seed(12345)
mydata <- data.frame(
race = sample(groupA, 100, replace=T, prob=c(.3,.3,.3,.01)),
Q_1 = sample(likert.responses, 100, replace=T, prob=c(.2,.2,.2,.2,.19,.01)),
Q_2 = sample(likert.responses, 100, replace=T, prob=c(.1,.2,.2,.29,.2, .01)),
Q_3 = sample(likert.responses, 100, replace=T, prob=c(.4,.2,.09,.15,.15,.01))
)
mydata.que <- mydata[questions]
mydata.que[] <- lapply(mydata.que, factor,
levels=c("Strongly disagree", "Disagree", "Neutral", "Agree","Strongly agree"))
mydata.1 <- likert(mydata.que)
mydata.group <- likert(mydata.que, grouping=mydata$race)
p <- plot(mydata.group, centered=F, # This controls stacked versus the "centered" option
ordered=F,
plot.percents = TRUE
) + ggtitle("Likert Test")
# --- Gets the percentages from the likert object -- #
results <- mydata.group$results
results <- reshape::melt(results, id=c('Group', 'Item'))
results$variable <- factor(results$variable, ordered=TRUE)
lpercentpos <- ddply(results[results$value > 0,], .(Group, Item), transform,
pos = cumsum(value) - 0.5*value)
lpercentpos <- subset(lpercentpos, variable != "Neutral" & value != 100 & value != 0)
# -- Double checking percents are right -- #
prop.table(table(mydata$race, mydata$Q_1),1)
pworks <- p + geom_text(data=lpercentpos, aes(x=Group, y=pos, label=paste0(round(value), '%'),
group=Item),
size=3)
pworks
# --- Using the OP's code --- #
p <- plot(likert.df.group, centered=F, # This controls stacked versus the "centered" option
ordered=F,
plot.percents = TRUE
) + ggtitle("Likert Test")
results <- likert.df.group$results
results <- reshape::melt(results, id=c('Group', 'Item'))
results$variable <- factor(results$variable, ordered=TRUE)
lpercentpos <- ddply(results[results$value > 0,], .(Group, Item), transform,
pos = cumsum(value) - 0.5*value)
lpercentpos <- subset(lpercentpos, variable != "Neutral" & value != 100 & value != 0)
prop.table(table(likert.df.group$race, likert.df.group$Q_1),1)
pworks <- p + geom_text(data=lpercentpos, aes(x=Group, y=pos, label=paste0(round(value), '%'),
group=Item),
size=3)
pworks
Even the example script that's included in the likert package documentation using the pisaitems data will not graph correctly the percent labels. It ends up looking like the image below when you run this code.
require(likert)
data(pisaitems)
##### Item 29: How often do you read these materials because you want to?
title <- "How often do you read these materials because you want to?"
items29 <- pisaitems[,substr(names(pisaitems), 1,5) == 'ST25Q']
head(items29); ncol(items29)
names(items29) = c("Magazines", "Comic books", "Fiction", "Non-fiction books", "Newspapers")
l29g <- likert(items29, grouping=pisaitems$CNT)
# Plots
plot(l29g, plot.percents=TRUE, plot.percent.low=FALSE,
plot.percent.high=FALSE, plot.percent.neutral=FALSE) +
ggtitle(title)
Hey I tried it out and it doesn't work for me either using the grouping data. There is no mention of why despite plot.percent.low and plot.percent.high working fine. Unless someone else cracks it all I can do is offer a workaround using plot() instead of likert.bar.plot and text()
Here I label the Agree category only for all three groups.
plot(likert.df.group, type="bar")
text(c(0.35,0.35,0.35), c(0.85,0.6,0.25),
labels = paste0(c(42.8,28.57,42.85),"%") )
I think this might have an easy answer - which I can't seem to find anywhere - so I'll forgo the reproducibility for the moment. I have a function designed to draw a ggplot2. I use mapply to pass it a few vectors of strings for the functions input parameters. The parameter of concern here is title. Which is fed a character vector with elements such as "this is a plot title".
Then the following code:
p <- ggplot(df, aes(x=date, y=value))
## plot the line
p <- p + geom_line()
## add plot title
p <- p + ggtitle(title)
actually works just fine and the plot title is "this is a plot title" as expected.
However if the title is long and I want to specify a point to wrap the title using \n it fails to work.
Precisely if I feed ggtitle an element of "this is a \n plot title". I get exactly that contained in the quotes, rather than wrapping the title at the \n. My suspicion is I need eval, or paste or get, but my formations of such a request have failed to achieve the desired results. I appreciate the help.
UPDATE:
I guess it must be the interaction with mapply. This should allow you to reproduce the problem.
create data.frame of strings as sample and assign it to fred.M.SA
structure(list(RegionalCoverage = c("National", "National", "National",
"National", "National", "National"), GeographicLevel = c("MSA",
"MSA", "MSA", "MSA", "MSA", "MSA"), Category = c("Workers", "Workers",
"Workers", "Workers", "Workers", "Workers"), Sector = c("Labor Market",
"Labor Market", "Labor Market", "Labor Market", "Labor Market",
"Labor Market"), Source2 = c("FRED", "FRED", "FRED", "FRED",
"FRED", "FRED"), Title = c("Unemployment Rate in La Crosse, WI-MN (MSA)",
"Trade, Transportation and Utilities Employment in La Crosse, WI-MN (MSA)",
"Professional and Business Services Employment in La Crosse, WI-MN (MSA)",
"Other Services Employment in La Crosse, WI-MN (MSA)", "Manufacturing Employment in La Crosse, WI-MN (MSA)",
"Leisure and Hospitality Employment \\n in La Crosse, WI-MN (MSA)"
), SeriesID = c("LACR155UR", "LACR155TRAD", "LACR155PBSV", "LACR155SRVO",
"LACR155MFG", "LACR155LEIH"), Units = c("%", "Thous. of Persons",
"Thous. of Persons", "Thous. of Persons", "Thous. of Persons",
"Thous. of Persons"), Freq = c("M", "M", "M", "M", "M", "M"),
Seas = c("SA", "SA", "SA", "SA", "SA", "SA"), OriginalSource = c("U.S. Department of Labor: Bureau of Labor Statistics",
"Federal Reserve Bank of St. Louis", "Federal Reserve Bank of St. Louis",
"Federal Reserve Bank of St. Louis", "Federal Reserve Bank of St. Louis",
"Federal Reserve Bank of St. Louis"), Method = c("ImportXML",
"ImportXML", "ImportXML", "ImportXML", "ImportXML", "ImportXML"
), LinktoSource = c("", "", "", "", "", ""), Link.to.Data.Spreadsheet.Name = c("",
"", "", "", "", ""), Link.to.Data.Storage = c("", "", "",
"", "", ""), Link.to.Data.Manipulation.File = c(NA, NA, NA,
NA, NA, NA), Link.to.Data.Manipulation.File.1 = c(NA, NA,
NA, NA, NA, NA)), .Names = c("RegionalCoverage", "GeographicLevel",
"Category", "Sector", "Source2", "Title", "SeriesID", "Units",
"Freq", "Seas", "OriginalSource", "Method", "LinktoSource", "Link.to.Data.Spreadsheet.Name",
"Link.to.Data.Storage", "Link.to.Data.Manipulation.File", "Link.to.Data.Manipulation.File.1"
), row.names = c(27L, 34L, 44L, 46L, 47L, 48L), class = "data.frame")
MakelineFred <- function(series, ylab="",xlab="", title="") {
require(ggplot2) # hadley's plotting framework
require(scales) # to adjust y axis scales
require(ggthemes) # extra themes including tufte
require(xts) # our favorite time series
require(gridExtra) # for adding a caption
require(timeDate) # for our prediction at the end
require(quantmod) #
# Get Data using quantmod
data <- getSymbols(series,src="FRED") #fred ignore from dates
# convert the string df to object df
data.xts <- get(data)
## convert data to data.frame
df <- data.frame(
date=as.Date(index(data.xts)),
value=as.numeric(data.xts))
p <- ggplot(df, aes(x=date, y=value))
## plot the line
p <- p + geom_line()
## add plot title
p <- p + ggtitle(title)
file <- paste("_",series,".png",sep="")
ggsave(file=file, plot=p, width=6, height=4)
finally here is the mapply call.
mapply(MakelineFred, series=fred.M.SA$SeriesID, title=fred.M.SA$Title)