Crops
Crops

Reputation: 5154

Plotting Dewey and Lu path analysis results as a Path diagram in R

I am trying to plot the outputs of a path analysis suggested by Dewey and Lu (1959) in R.

require(agricolae)
require(Hmisc)

data(wilt)
data(soil)
x<-soil[,c(3,12,14,20)]
y<-wilt[,14]
data <- cbind(y,x)
#Correlation of independant variables
cor.x <- rcorr(as.matrix(x))$r
#Correlation of dependant variable with all the independant variables
cor.y <- as.data.frame(t(subset(rcorr(as.matrix(cbind(y,x)))$r, select = c(y))))[,-1]
#Path Analysis
Path <- path.analysis(cor.x,cor.y)
#Direct Effects
diag(Path$Coeff)
#Residual Effects
Path$Residual

I want to plot the direct effects of independent variables to the dependent variable y and the correlations among the dependent variables as follows along with the residual effect.

enter image description here

I have tried semPlot and path.diagram {sem} and qgraph.lavaan, but they plot the model only. pathdiagram does not plot edge labels (path coefficients and correlations). How to do it in R?

This is as far as I got using the `diagram package.

par(mar = c(1, 1, 1, 1))
openplotmat()
# Get plot coordinates
elpos <- coordinates (c(2, length(cor.y)))
# adjust coordinates for Residual
elpos[2,1] <- abs((elpos[1,1]+elpos[1,2])/2)


#Specify Arrow positions
#1 Residual to Dependent
ft1 <- matrix(ncol = 2, byrow = TRUE, data = c(1, 2))
#2 Independent to dependent
ft2 <- matrix(ncol=2, byrow = FALSE, 
              data= c(seq((2+length(cor.y)))[3:(length(cor.y)+2)], rep(2, length(cor.y))))
#3 For cor.x
fromto_CU <- t(combn(seq((2+length(cor.y)))[3:(length(cor.y)+2)],2))
#4 For path distances
fromto_ST <- rbind(ft1,ft2)

# Plot Path distance arrows
nr <- nrow(fromto_ST)
arrpos <- matrix(ncol = 2, nrow = nr)
for (i in 1:nr)
  arrpos[i, ] <- straightarrow (to = elpos[fromto_ST[i, 2], ],
                                from = elpos[fromto_ST[i, 1], ],
                                lwd = 2, arr.pos = 0.6, arr.length = 0.5)

#Label residual path distance arrow
text(arrpos[1, 1], arrpos[1, 2] + 0.05, 
     paste("P", "X", nrow(cor.x)+1," = ", round(Path$Residual, 2), sep=""), cex=0.6)

#Label path distance arrows
nr <- nrow(arrpos)
for(i in 2:nr){
  text(arrpos[i, 1], arrpos[i, 2] + 0.05, 
       paste("P", "X", i-1," = ", round(diag(Path$Coeff)[i-1], 2), sep=""), cex=0.6)
}

# Plot correlation arrows direction 1
nr <- nrow(fromto_CU)
arrpos <- matrix(ncol = 2, nrow = nr)
for (i in 1:nr)
  arrpos[i, ] <- curvedarrow (to = elpos[fromto_CU[i, 2], ],
                                from = elpos[fromto_CU[i, 1], ],
                                lwd = 2, arr.pos = 0.8, arr.length = 0.5, curve = 0.35)

# Plot correlation arrows - direction 2
nr <- nrow(fromto_CU)
arrpos <- matrix(ncol = 2, nrow = nr)
for (i in 1:nr)
  arrpos[i, ] <- curvedarrow (to = elpos[fromto_CU[i, 1], ],
                              from = elpos[fromto_CU[i, 2], ],
                              lwd = 2, arr.pos = 0.8, arr.length = 0.5, curve = -0.35)

# Create combinations of cor.x for labelling rxy in correlation arrows
rcomb <- as.data.frame(t(combn(seq(nrow(cor.x)),2)))
rcomb <- paste(rcomb$V1,rcomb$V2, sep="")

# Label correlation arrows
nr <- nrow(fromto_CU)
arrpos <- matrix(ncol = 2, nrow = nr)
for (i in 1:nr)
  arrpos[i, ] <- curvedarrow (to = elpos[fromto_CU[i, 1], ],
                              from = elpos[fromto_CU[i, 2], ],
                              lwd = 2, arr.pos = 0.5, lcol = "transparent", arr.length = 0.5, curve = -0.35)

nr <- nrow(arrpos)
for(i in 1:nr){
  text(arrpos[i, 1], arrpos[i, 2] + 0.05, 
       paste("r", "X", rcomb[i]," = ", round(as.dist(cor.x)[i], 2), sep=""), cex=0.6)
}

# Label Residual
textrect (elpos[1,], 0.09, 0.03,lab = "Residual", box.col = "white",
          shadow.col = "grey", shadow.size = 0.005, cex = 1)
# Label Dependent
textrect (elpos[2,], 0.09, 0.03,lab = attributes(y)$class, box.col = "white",
          shadow.col = "grey", shadow.size = 0.005, cex = 1)
# Label independents
nr <- nrow(elpos)
for (i in 3:nr){
  textrect (elpos[i,], 0.09, 0.03,lab = colnames(x)[i-2], box.col = "white",
            shadow.col = "grey", shadow.size = 0.005, cex = 1)
}

enter image description here

I need some help for

1) Plotting on a horizontal layout in diagram, so that the plot looks like the first one

2) Plotting subscripts in the arrow labels such as PX5, r12, r34 etc. Combination of expression and paste in the loops used returns the indexing notation as such and not the indexed element.

Upvotes: 4

Views: 3135

Answers (1)

Carl Witthoft
Carl Witthoft

Reputation: 21532

You may find it quicker in the long run just to use tools like text to place text where you want it on your drawing. I don't know what parameters are used to define the diagonal lines with your "P25 = -0.37" and similar labels, but on the assumption that you do know each line's coordinates (endpoints, e.g.), you could use plotrix:radialtext .

Upvotes: 1

Related Questions