简体   繁体   中英

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) ) )  )

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM