[R] User defined panel functions in lattice

Duncan Mackay mackay at northnet.com.au
Thu Apr 19 10:30:24 CEST 2012


Hi

I have a problem with passing line and symbol parameters to user 
defined panel functions
I had a look at the archives and created a panel function on what was 
shown and on panel.loess.
I could not to get panel.locfit to work for what I intend it for.
There is another layer to work with before success as lp() is called 
from locfit.

xx <-
structure(list(Farm = c("A", "A", "A", "A", "A", "A", "A", "A",
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C",
"C", "C", "C", "C", "C", "C", "C"), Padd = c(1L, 2L, 1L, 2L,
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L), x = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L,
7L, 7L, 8L, 8L, 9L, 9L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L,
6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L,
5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L), y = c(-0.0149119113575325,
-2.06204168532879, 0.59115620108342, 0.701065909641364, -0.09209267129213,
-0.865247821447864, 0.0241230046650827, 1.07765163669472, 0.0861209136257006,
-0.0432194108428863, 1.0752878640701, -0.324831311786088, 1.23524270758109,
1.37506065481906, 0.653119800000345, 0.343529478624465, -1.02800469514037,
0.621939148133714, -0.472190923018883, 0.341027069452984, 0.346279582846995,
0.0315430632529719, -0.0485334640758356, -0.49139051657477, 1.28653851743574,
0.397753324159675, -2.75735912593535, -1.25477580809239, 0.0210974048006148,
-1.77042148383975, 0.505895481518074, 1.80124546723389, -0.626702949092294,
-0.417560134229316, -0.0590225862046547, -0.252886465059564,
-1.47678447981784, -1.18297973979234, 0.204487915335494, -0.264105749006465,
-2.22751785897293, 1.93698185670379, -0.51664334633059, 0.400028987594472,
1.55840082305276, 0.309921251997392, -0.229844761531488, -0.0571710727247884,
-1.63022881763476, 0.447916795447731, -0.583450668171441, -2.09617753882993,
-1.78560353982556, -0.872155343528674)), .Names = c("Farm", "Padd",
"x", "y"), row.names = c(NA, -54L), class = "data.frame")

   library(locfit)
   panel.Locfit <-
   function(x,y, nn, h, col, col.line, lwd = lwd, lty = lty, ...){

     if (missing(nn) ) nn <- 0.7
     if (missing(h) ) h <- 0

     if (!missing(col)) {
         if (missing(col.line))
             col.line <- col
     }

     # locfit regression
     xy.loc <- locfit(y ~ lp(x, nn = nn, h = h) )
     # newdata
     xvals <- sort(unique(x))

     # predictions
     xy.loc.pre <-
     predict(xy.loc, newdata = list(x = xvals), se.fit = TRUE)

     u.vals <- xy.loc.pre$fit + 2*xy.loc.pre$se.fit  # upper
     l.vals <- xy.loc.pre$fit - 2*xy.loc.pre$se.fit  # lower

     # fit
     llines(xvals, xy.loc.pre$fit,
            type= "l",
            lwd = lwd,
            lty = lty,
            col = col.line)

   } ## panel.locfit

   xyplot(y ~x|Farm,xx,
          groups = Padd,
          par.settings = list(strip.background = list(col = "transparent"),
                              superpose.line   = list(col = c("black","grey"),
                                                              lwd = c(1,2),
                                                              lty = c(2,1)),
                              superpose.symbol = list(cex = c(0.8, 0.7),
                                                      col = c("red","black"),
                                                      pch = c(20,4))
                    ),
          auto.key=list(lines=T,points = T,rectangles=F),
          panel = panel.superpose,
          panel.groups=function(x,y, ...){

                         panel.Locfit(x,y,...)
                         panel.xyplot(x,y,...)
                       }
   ) ## xyplot

The above works nicely and also without par.setting giving lattice defaults.
The par.setting is handy for a lot of graphs that I do.

But when I tried a 1 panel plot I get the error message.

   xyplot(y ~x,xx,
          groups = Farm,
          auto.key=TRUE,
          panel = function(x,y, ...){

                         panel.Locfit(x,y,...)
                         panel.xyplot(x,y,...)
                       }
          )

#  Error using packet 3
# promise already under evaluation: recursive default argument 
reference or earlier problems?

If I want to plot another curve with different smoothing it is OK 
with the defaults and par.settings e.g. with the line added

                         panel.Locfit(x,y,nn= 0.9, ...)

but gives an error message without par.settings if i want to add
                         panel.Locfit(x,y,nn= 0.9,lwd = c(1,2,3), ...)

Error using packet 1
formal argument "Iwd" matched by multiple actual arguments

I also need to plot a smoothed line for all groups trying groups, 
subscripts and panel.groups as arguments without success

Any solutions to solve the above will be gratefully received and 
faithfully applied.

Duncan

sessionInfo()
R version 2.15.0 (2012-03-30)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] 
LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252 
LC_MONETARY=English_Australia.1252 
LC_NUMERIC=C                       LC_TIME=English_Australia.1252

attached base packages:
[1] datasets  utils     stats     graphics  grDevices 
grid      methods   base

other attached packages:
[1] 
locfit_1.5-7        R.oo_1.9.3          R.methodsS3_1.2.2 
foreign_0.8-49      chron_2.3-42        MASS_7.3-17 
latticeExtra_0.6-19 RColorBrewer_1.0-5
[9] lattice_0.20-6

loaded via a namespace (and not attached):
[1] tools_2.15.0



Duncan Mackay
Department of Agronomy and Soil Science
University of New England
ARMIDALE NSW 2351
Email home: mackay at northnet.com.au



More information about the R-help mailing list