col and row names in a Forest plot - r

I don't how to introduce columns and rows names into a forest plot. Here is the dataset:
structure(list(structure(c(5L, 6L, 4L, 3L, 2L, 1L), .Label = c("Austria",
"Denmark", "England", "France", "Portugal", "Spain"), class = "factor"),
Slope = c(-1.8511, -2.33305, -2.698, -1.46, -0.98, -1.401
), low = c(-3.3021, -4.305, -5.873, -4.86, -5.082, -2.887
), high = c(-0.4008, -0.364, -0.087, 2.98, 3.125, -0.054),
bS0 = c(-5.66, -2.709, -4.057, -1.224, -0.574, -1.43), Sf = c(0.354,
0.169, 0.253, 0.077, 0.036, 0.089), `S0-Sf` = c(0.146, 0.126,
0.169, 0.091, 0.061, 0.088)), .Names = c("", "Slope", "low",
"high", "bS0", "Sf", "S0-Sf"), class = "data.frame", row.names = c(NA,
-6L))
And here the script to get the Forest plot:
windows()
forestplot(labeltext=data, graph.pos=3,
mean=c(data$Slope),
lower=c(data$low), upper=c(data$high),
xlab="Regression Coefficient",
txt_gp=fpTxtGp(label=gpar(cex=1),
ticks=gpar(cex=1),
xlab=gpar(cex = 1),
title=gpar(cex = 1)),
col=fpColors(box="black", lines="black", zero = "gray50"),
zero=0, cex=0.9, lineheight = "auto", boxsize=0.1,
lwd.ci=1, ci.vertices=TRUE, ci.vertices.height = 0.1,colgap=unit(4,"mm"))
And here is the outcome:
However, I would like to introduce the names of the countries (column 1 of my data) and the columns names. How should I do it?

I don't know how to modify you solution, so I did it my way:
data <-
structure(list(
coef = c(NA,-1.85110, -2.33305, -2.69800, -1.46000, -0.98000, -1.40100),
low = c(NA,-3.3021, -4.3050, -5.8730, -4.8600, -5.0820, -2.8870),
high = c(NA,-0.4008, -0.3640, -0.0870, 2.9800, 3.1250, -0.0540)),
.Names = c("coef", "low", "high"),
row.names = c(NA, -7L),
class = "data.frame")
tabletext<-cbind(c(NA,"Portugal","Spain","France","Engald","Denmark","Austria"),
c("Slope", "-1.8511", "-2.33305", "-2.698", "-1.46", "-0.98", "-1.401"),
c("low", "-3.3021", "-4.305", "-5.873", "-4.86", "-5.082", "-2.887"),
c("high", "-0.4008", "-0.364", "-0.087", "2.98", "3.125", "-0.054"),
c("bS0", "-5.66", "-2.709", "-4.057", "-1.224", "-0.574", "-1.43"),
c("Sf", "-0.354", "0.169", "0.253", "0.077", "0.036", "0.089"),
c("S0-Sf", "0.146", "0.126", "0.169", "0.091", "0.061", "0.088"))
forestplot(tabletext,
data,new_page = TRUE,
clip=c(-6,3),
boxsize = .25,
graphwidth = unit(10, "cm"),
xlog=F,
col=fpColors(line="black"),
xlab="Regression Coefficient")

You need to use graph.pos argument inside the forestplot function.
For example, use graph.position=3 if you want the plot after the slope column

Related

How do I change the shape of the lines in a plot generated by a for loop?

I'm not sure how to change the shape and color of the for loop for data in a df, fish
structure(list(Region = structure(c(7L, 7L, 7L, 7L, 7L), .Label = c("American Samoa",
"Johnston Atoll", "Line Islands", "MHI", "Musicians Seamounts",
"Northern Marianas", "NWHI", "Southern Marianas", "Tokelau Ridge",
"Wake Island"), class = "factor"), ObservationYear = c(2015,
2015, 2015, 2015, 2015), `Mega-Habitat` = c("bank", "bank", "tablemount",
"bank", "atoll"), Total_fish = c(6, 10, 21, 11, 7), Lat = c(23.2227305,
25.0840027, 26.8267143809524, 26.8188378, 27.5178584285714),
Long = c(-163.516748333333, -172.490419, -175.607307619048,
-176.315991, -175.460592857143), Temperature = c(1.82256666666667,
2.00518, 3.03555714285714, 2.01533, 1.5475), Salinity = c(34.64115,
34.61702, 34.4760619047619, 34.61106, 34.6673857142857),
Oxygen = c(3.16008333333333, 2.79735, 1.27077619047619, 2.58692,
3.73167142857143), Distance = c(350, 960, 1130, 360, 460),
`CTD Availability` = c(NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_), depth_bin = c("2000-3000",
"1000-2000", "1000-2000", "1000-2000", "2000-3000"), EventID = c("D2-EX1504L2-01",
"D2-EX1504L2-06", "D2-EX1504L2-08", "D2-EX1504L2-10", "D2-EX1504L2-12"
), Average_Depth = c(2160.20383333333, 1880.4596, 1217.94385,
1890.1868, 2780.92557142857), POC_Flux = c(2.56732258067581,
2.86961424536357, 3.38129564627503, 3.38129564627503, 3.80216410589398
)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"
))
I ran a GAM before the loop:
g1 = mgcv::gam(Total_fish ~ s(Average_Depth, by = Region) + Region + offset(log(Distance)), data =fish,family= nb)
I tried defining shapes, but it did not work
shapes= c(0,1,2,3,4,5,6,7,8,9,10)
shapes <-shapes[as.numeric(fish$Region)]
colors.use = rainbow(nlevels(fish$Region))
for (i in 1:nlevels(fish$Region)) {
predictions = predict(g1, type="response", newdata = data.frame(Distance= 1000, Average_Depth = seq(0,3000,length=1000), Region = levels(fish$Region)[i]))
if (i == 1) plot(xlab= "Depth (m)", ylab = "fish/1000 m",seq(0,3000,length=1000), predictions, type = 'l', col=colors.use[i], pch=i)
if (i > 1) lines(seq(0,3000,length=1000), predictions,col=colors.use[i],pch=i)
}
I just need to be able to differentiate between the regions and the current rainbow colors alone are not very useful for that

R, how to change to interval in the y axis of a forest plot?

I'm preparing e a forest plot in R through the forestplot package. The possible values range from -1 to +1, and I would like that to be the range on my x axis. My values, however, range from 0 to 1, so R is depicting only that part on the x axis.
See the image here:
How can I make the x axis interval range from -1 to +1? I want to leave a complete empty space on the right to show no value is there.
Here's my code:
library("forestplot")
cochrane_from_rmeta <-
structure(list(
lower = c(NA, NA, 0.026, 0.043, 0.184, 0.333, 0.026),
mean = c(NA, NA, 0.502, 0.534, 0.548, 0.792, 0.600),
upper = c(NA, NA, 0.978, 0.949, 0.911, 0.936, 0.967)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -7L),
class = "data.frame")
tabletext<-cbind(
c("", "aaa", "bbb", "ccc",
"ddd", "eee",
"Summary"),
c("", "#datasets", "1", "2",
"3", "4",
NA))
png(paste0("forestPlot_",exe_num,".png"))
forestplot(tabletext,
cochrane_from_rmeta,
new_page = TRUE,
is.summary=c(TRUE,TRUE,rep(FALSE,4),TRUE),
clip=c(-1,1),
xlog=FALSE,
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"))
There doesn't seem to be a direct way of doing this, but if you set a lower and upper of -1 and 1 in your first row while leaving mean as NA, it will fix the x range without affecting the plot otherwise:
cochrane_from_rmeta <-
structure(list(
lower = c(-1, NA, 0.043, 0.043, 0.184, 0.333, 0.026),
mean = c(NA, NA, 0.502, 0.534, 0.548, 0.792, 0.600),
upper = c(1, NA, 0.978, 0.949, 0.911, 0.936, 0.967)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -7L),
class = "data.frame")
tabletext<-cbind(
c("", "aaa", "bbb", "ccc",
"ddd", "eee",
"Summary"),
c("", "#datasets", "1", "2",
"3", "4",
NA))
forestplot(tabletext,
cochrane_from_rmeta,
new_page = TRUE,
is.summary=c(FALSE,TRUE,rep(FALSE,4),TRUE),
clip=c(-1,1),
xlog=FALSE,
mar = unit(c(50, 30, -30, 30), "pt"),
col=fpColors(box="royalblue",line="darkblue", summary="royalblue"),
graphwidth = unit(0.7, "npc"))

How to squeeze rows together in forestplot using forestplot package in R

I'm making a forest plot using the forestplot package in R. I have a lot of white space between the rows in my plot. How can I remove the space, or squeeze the rows together, to make a neater smaller graph? Many thanks.
library(forestplot)
main5 <-
structure(list(
mean = c(NA, NA, 0.80, 0.90, 0.7, 1.2),
lower = c(NA, NA, 0.70, 0.50, 0.59, 1.11),
upper = c(NA, NA, 1.02, 1.25, 1.04, 1.94)),
.Names = c("mean", "lower", "upper"),
row.names = c(NA, -6L),
class = "data.frame")
tabletext5<-cbind(
c("", "Analysis", "Outcome: X", Outcome: Y", "Outcome: Z", "Outcome: xx"),
c("", "A
time", "115987.8", "117604.4", "118518.6","115493.2"),
c("", "A
Outcomes", "813", "51", "715", "2114"),
c("", "B
time", "114516.2", "118728.5", "117896.2","119096.3"),
c("", "B
Outcomes", "1199", "71", "911","1109"),
c("", "HR", "0.8", "0.9", "0.7", "1.2"),
c("", "99% CI", "0.70, 1.02", "0.50, 1.25", "0.59, 1.04", "1.11, 1.94"))
forestplot(tabletext5,
main5,new_page = TRUE,
hrzl_lines=list("3" = gpar(lwd=1, col="#444444")),
is.summary=c(TRUE, TRUE, rep(FALSE, 5)),
txt_gp = fpTxtGp(label=gpar(cex=0.7)
),
boxsize=0.3,
xlog=T,
graphwidth = unit(9, "cm"),
graphheight = unit(6, "cm"),
clip= c(0.5, 3.0),
xticks=c(0.5, 1.0, 1.5, 2.0, 2.5),
xlab=" B worse A worse ",
fs.xlab=60,
col=fpColors(box="#7570B3",line="#7570B3")) ##have picked the blue colour from the "dark2 palette
lineheight property in the forestplot() does the job
forestplot(your_table, lineheight='lines')
If You want to set a custom height, use lineheight=unit(1,'cm'), where the the expected value is float.

Add median trend line and p-value for one-sided repeated measures test in 2-y axis scatter plot [R]

Load sample data frame
df <- structure(list(ID = c(1,1,1,2,2,2,3,3,3),
time = c(0L,1L,2L,0L,1L,2L,0L,1L,2L),
M1a = c(0, 0.2, 0.3, 0, 1.5, 2.9,0, 2.4, 3.9),
M2a = c(0, 0.4, 0.6,0,0.9, 0.9,0,0.5, 0.7),
M3a = c(0,0.3, 0.4, 0, 0.6, 0.9,0, 0.5, 0.8),
M4a = c(0,0.6, 0.6,0, 0.4, 0.6,0, 0.2, 0.9),
M1b = c(0L, 200L, 300L,0L, 300L, 900L,0L, 900L, 1000L),
M2b = c(0L, 400L, 600L,0L, 600L, 900L,0L, 600L, 1000L),
M3b = c(0L, 300L, 400L,0L, 200L, 800L,0L, 200L, 900L),
M4b = c(0L, 600L, 600L,0L, 800L, 1000L,0L, 400L, 1100L)),
.Names = c("ID", "time", "M1a", "M2a", "M3a", "M4a","M1b", "M2b","M3b", "M4b"), class = "data.frame", row.names = c(NA, -9L))
Now plot two y-axis scatter plot
par(mar=c(5,4,4,5)+.1)
plot(df$time,df$M1a,type="p",col="red", main="M1", cex=0.5, cex.main=2, cex.lab=1.0, cex.axis=0.7)
par(new = TRUE)
plot(df$time,df$M1b,type="p",col="blue",xaxt="n",yaxt="n",xlab="",ylab="")
mtext("Relative change (%)",side=4,line=3)
axis(4)
legend("topleft",col=c("red","blue"),lty=1,legend=c("Absolute Change","Relative Change"))
What I am stuck with?
1.Median trend line
I was able to add regression line, but I want to have a median trend line connecting M1a and M1b medians for three time points.
2.Adding p-values to the plot, repeated one-way anova test
fit1=aov(df$M1a~df$time + Error(ID/time),na.action=na.exclude,data=df);
sig1= summary(fit1)$"Error: Within"$"Pr(>F)"
if (sig<0.001) star='**' else if (sig>=0.001&sig<0.05) star='*' else star='';
if (sig1<0.001) star='**' else star='';
I was planning to add use above code for adding p-value in my 2-y axis plot. Here, I get sig1 as NULL, however, sig1 should print out 0.153.
The final results should include * mark on the main title of plot (M1), if results are significant.
Any tips? Thanks in advance!
To answer #2 first, one needs to look at the inner structures of a summary.aov object:
dput(summary(fit1))
structure(list(`Error: ID` = structure(list(structure(list(Df = 1,
`Sum Sq` = 5.60666666666667, `Mean Sq` = 5.60666666666667,
`F value` = NA_real_, `Pr(>F)` = NA_real_), .Names = c("Df",
"Sum Sq", "Mean Sq", "F value", "Pr(>F)"), class = c("anova",
"data.frame"), row.names = "Residuals")), class = c("summary.aov",
"listof")), `Error: ID:time` = structure(list(structure(list(
Df = 1, `Sum Sq` = 11.3157142857143, `Mean Sq` = 11.3157142857143), .Names = c("Df",
"Sum Sq", "Mean Sq"), class = c("anova", "data.frame"), row.names = "df$time")), class = c("summary.aov",
"listof")), `Error: Within` = structure(list(structure(list(Df = c(1,
5), `Sum Sq` = c(0.325952380952381, 0.573888888888889), `Mean Sq` = c(0.325952380952381,
0.114777777777778), `F value` = c(2.83985617480293, NA), `Pr(>F)` = c(0.152766396924706,
NA)), .Names = c("Df", "Sum Sq", "Mean Sq", "F value", "Pr(>F)"
), class = c("anova", "data.frame"), row.names = c("df$time ",
"Residuals"))), class = c("summary.aov", "listof"))), .Names = c("Error: ID",
"Error: ID:time", "Error: Within"), class = "summary.aovlist")
And note that the values within summary(fit1)$"Error: Within" are actually buried one level deeper (and don't have names so need numeric index. Do this:
summary(fit1)$"Error: Within"[[1]]$`Pr(>F)`
[1] 0.1527664 NA
Now to see if I can figure out the two-0rdinate plot issue. Pretty sure one would need to do any median plotting before the par(new=TRUE) operation because that changes the user coordinate system based on the new data.
Adding a title with extracted value to your plot augmented by the helpful comment by #VincentBonhomme:
plot(df$time,df$M1a,type="p",col="red", cex=0.5, cex.main=2, cex.lab=1.0, cex.axis=0.7)
lines(unique(df$time),
tapply(df$M1a, df$time, median))
par(new = TRUE)
plot( df$time, df$M1b,type="p", col="blue", xaxt="n", yaxt="n", xlab="",ylab="")
lines(unique(df$time),
tapply(df$M1b, df$time, median))
mtext("Relative change (%)",side=4,line=3)
axis(4)
legend("topleft",col=c("red","blue"), lty=1,legend=c("Absolute Change","Relative Change"))
title(main=bquote("P-value for M1 (absolute scale)"==
.(round(summary(fit1)$"Error: Within"[[1]]$`Pr(>F)`, 3) ) ) )

error : ggplot2 doesn't know how to deal with data of class uneval

I have this code
ggplot() +
stat_density(kernel = "biweight",aes(x=fd, colour=id), data=foo1,position="identity",geom="line")+
coord_cartesian(xlim = c(0, 200))+
xlab("Flood Duration")+
ylab("Density")+
ggtitle("PDFs of Flood Duration")+
ggsave("pdf_fd_conus.png")
And I wrote this function
pdf.plot<-function(data,x,xl,yl,title,save){
ggplot() +
stat_density(data, kernel = "biweight",aes_string(x=x, colour='id'),
position="identity",geom="line")+
coord_cartesian(xlim = c(0, 200))+
xlab(xl)+
ylab(yl)+
ggtitle(title)+
ggsave(save)
}
Calling using this:
pdf.plot(data=foo1,x='fd',xl='b',
yl='a',title='a',save='y.png')
But I am getting this error:
Error: ggplot2 doesn't know how to deal with data of class uneval
Called from: eval(expr, envir, enclos)
This is dput(head(foo1,4))
structure(list(id = structure(c(1L, 1L, 1L, 1L), .Label = c("dfa",
"dfb", "cfa", "csb", "bsk"), class = "factor"), lon = c(-70.978611,
-70.978611, -70.945278, -70.945278), lat = c(42.220833, 42.220833,
42.190278, 42.190278), peakq = c(14.7531, 17.3865, 3.3414, 2.7751
), area = c(74.3327, 74.3327, 11.6549, 11.6549), fd = c(29, 54.75,
23, 1), tp = c(14.25, 19.75, 13.5, 0.5), rt = c(14.75, 35, 9.5,
0.5), bl = c(15485.3, 15485.3, 8242.64, 8242.64), el = c(0.643551,
0.643551, 0.474219, 0.474219), k = c(0.325279, 0.325279, 0.176624,
0.176624), r = c(81.947, 81.947, 38.7003, 38.7003), si = c(0.0037157,
0.0037157, -9999, -9999), rr = c(0.00529193, 0.00529193, 0.00469513,
0.00469513)), .Names = c("id", "lon", "lat", "peakq", "area",
"fd", "tp", "rt", "bl", "el", "k", "r", "si", "rr"), row.names = c(NA,
4L), class = "data.frame")
Could you please help?
Your problem is that you didn't specify what argument data is in stat_density. If you look at ?stat_density you'll see the first implied argument is actually mapping=. You need to change pdf.plot to:
pdf.plot<-function(data,x,xl,yl,title,save){
ggplot() +
stat_density(data = data, kernel = "biweight",aes_string(x=x, colour='id'),
position="identity",geom="line")+
coord_cartesian(xlim = c(0, 200))+
xlab(xl)+
ylab(yl)+
ggtitle(title)+
ggsave(save)
}

Resources