verInd= and HorInd= arguments to pairs() function

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

verInd= and HorInd= arguments to pairs() function

Andrews, Chris

After making scatterplot matrix, I determined I only needed the first 2 columns of the matrix so I added verInd=1:2 to my pairs() call.  However, it did not turn out as I expected.

Perhaps the attached pdf of the example code will make it through.  If not, my description is "the wrong scatterplot pairs are in the wrong places" for the last two pairs() calls.

Thanks,
Chris

################################################################

# fake data
xmat <- matrix(1:28, ncol=4)
lim <- range(xmat)

# what I expected
pairs(xmat, xlim=lim, ylim=lim) # 4x4 matrix of scatterplots
pairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:2) # 2x2 matrix of scatterplots: upper left

# here comes trouble
pairs(xmat, xlim=lim, ylim=lim, horInd=1:2) # 2x4 matrix of scatterplots: but not the top 2 rows (or bottom 2 rows)
pairs(xmat, xlim=lim, ylim=lim, verInd=1:2) # 4x2 matrix of scatterplots: but not the left 2 columns (or right 2 columns)


###############################################################

> sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

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

loaded via a namespace (and not attached):
[1] compiler_3.5.0 tools_3.5.0  
**********************************************************
Electronic Mail is not secure, may not be read every day, and should not be used for urgent or sensitive issues

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

pairs.pdf (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Gerrit Eichner
Hi, Chris,

had the same problem (and first thought it was my fault), but there
seems to be a typo in the code of pairs.default. Below is a workaround.
Look for two comments (starting with #####) in the code to see what I
have changed to make it work at least the way I'd expect it in one of
your examples.

  Hth --  Gerrit


mypairs <- function (x, labels, panel = points, ...,
     horInd = 1:nc, verInd = 1:nc,
     lower.panel = panel, upper.panel = panel, diag.panel = NULL,
     text.panel = textPanel, label.pos = 0.5 + has.diag/3, line.main = 3,
     cex.labels = NULL, font.labels = 1, row1attop = TRUE, gap = 1,
     log = "") {
     if (doText <- missing(text.panel) || is.function(text.panel))
         textPanel <- function(x = 0.5, y = 0.5, txt, cex, font) text(x,
             y, txt, cex = cex, font = font)
     localAxis <- function(side, x, y, xpd, bg, col = NULL, main,
         oma, ...) {
         xpd <- NA
         if (side%%2L == 1L && xl[j])
             xpd <- FALSE
         if (side%%2L == 0L && yl[i])
             xpd <- FALSE
         if (side%%2L == 1L)
             Axis(x, side = side, xpd = xpd, ...)
         else Axis(y, side = side, xpd = xpd, ...)
     }
     localPlot <- function(..., main, oma, font.main, cex.main) plot(...)
     localLowerPanel <- function(..., main, oma, font.main, cex.main)
lower.panel(...)
     localUpperPanel <- function(..., main, oma, font.main, cex.main)
upper.panel(...)
     localDiagPanel <- function(..., main, oma, font.main, cex.main)
diag.panel(...)
     dots <- list(...)
     nmdots <- names(dots)
     if (!is.matrix(x)) {
         x <- as.data.frame(x)
         for (i in seq_along(names(x))) {
             if (is.factor(x[[i]]) || is.logical(x[[i]]))
                 x[[i]] <- as.numeric(x[[i]])
             if (!is.numeric(unclass(x[[i]])))
                 stop("non-numeric argument to 'pairs'")
         }
     }
     else if (!is.numeric(x))
         stop("non-numeric argument to 'pairs'")
     panel <- match.fun(panel)
     if ((has.lower <- !is.null(lower.panel)) && !missing(lower.panel))
         lower.panel <- match.fun(lower.panel)
     if ((has.upper <- !is.null(upper.panel)) && !missing(upper.panel))
         upper.panel <- match.fun(upper.panel)
     if ((has.diag <- !is.null(diag.panel)) && !missing(diag.panel))
         diag.panel <- match.fun(diag.panel)
     if (row1attop) {
         tmp <- lower.panel
         lower.panel <- upper.panel
         upper.panel <- tmp
         tmp <- has.lower
         has.lower <- has.upper
         has.upper <- tmp
     }
     nc <- ncol(x)
     if (nc < 2L)
         stop("only one column in the argument to 'pairs'")
     if (!all(horInd >= 1L && horInd <= nc))
         stop("invalid argument 'horInd'")
     if (!all(verInd >= 1L && verInd <= nc))
         stop("invalid argument 'verInd'")
     if (doText) {
         if (missing(labels)) {
             labels <- colnames(x)
             if (is.null(labels))
                 labels <- paste("var", 1L:nc)
         }
         else if (is.null(labels))
             doText <- FALSE
     }
     oma <- if ("oma" %in% nmdots)
         dots$oma
     main <- if ("main" %in% nmdots)
         dots$main
     if (is.null(oma))
         oma <- c(4, 4, if (!is.null(main)) 6 else 4, 4)
     opar <- par(mfcol = c(length(horInd), length(verInd)),
##### Changed from mfrow to mfcol
                 mar = rep.int(gap/2, 4), oma = oma)
     on.exit(par(opar))
     dev.hold()
     on.exit(dev.flush(), add = TRUE)
     xl <- yl <- logical(nc)
     if (is.numeric(log))
         xl[log] <- yl[log] <- TRUE
     else {
         xl[] <- grepl("x", log)
         yl[] <- grepl("y", log)
     }
     for (j in if (row1attop) verInd else rev(verInd))
      for (i in horInd) {
##### Exchanged i and j. (i used to be in
##### the outer and j in the inner loop!)
         l <- paste0(ifelse(xl[j], "x", ""), ifelse(yl[i], "y", ""))
         localPlot(x[, j], x[, i], xlab = "", ylab = "", axes = FALSE,
             type = "n", ..., log = l)
         if (i == j || (i < j && has.lower) || (i > j && has.upper)) {
             box()
             if (i == 1 && (!(j%%2L) || !has.upper || !has.lower))
                 localAxis(1L + 2L * row1attop, x[, j], x[, i],
                   ...)
             if (i == nc && (j%%2L || !has.upper || !has.lower))
                 localAxis(3L - 2L * row1attop, x[, j], x[, i],
                   ...)
             if (j == 1 && (!(i%%2L) || !has.upper || !has.lower))
                 localAxis(2L, x[, j], x[, i], ...)
             if (j == nc && (i%%2L || !has.upper || !has.lower))
                 localAxis(4L, x[, j], x[, i], ...)
             mfg <- par("mfg")
             if (i == j) {
                 if (has.diag)
                   localDiagPanel(as.vector(x[, i]), ...)
                 if (doText) {
                   par(usr = c(0, 1, 0, 1))
                   if (is.null(cex.labels)) {
                     l.wid <- strwidth(labels, "user")
                     cex.labels <- max(0.8, min(2, 0.9/max(l.wid)))
                   }
                   xlp <- if (xl[i])
                     10^0.5
                   else 0.5
                   ylp <- if (yl[j])
                     10^label.pos
                   else label.pos
                   text.panel(xlp, ylp, labels[i], cex = cex.labels,
                     font = font.labels)
                 }
             }
             else if (i < j)
                 localLowerPanel(as.vector(x[, j]), as.vector(x[,
                   i]), ...)
             else localUpperPanel(as.vector(x[, j]), as.vector(x[,
                 i]), ...)
             if (any(par("mfg") != mfg))
                 stop("the 'panel' function made a new plot")
         }
         else par(new = FALSE)
     }
     if (!is.null(main)) {
         font.main <- if ("font.main" %in% nmdots)
             dots$font.main
         else par("font.main")
         cex.main <- if ("cex.main" %in% nmdots)
             dots$cex.main
         else par("cex.main")
         mtext(main, 3, line.main, outer = TRUE, at = 0.5, cex = cex.main,
             font = font.main)
     }
     invisible(NULL)
}



## Example:

mypairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:4)



Am 06.06.2018 um 23:55 schrieb Andrews, Chris:

>
> After making scatterplot matrix, I determined I only needed the first 2 columns of the matrix so I added verInd=1:2 to my pairs() call.  However, it did not turn out as I expected.
>
> Perhaps the attached pdf of the example code will make it through.  If not, my description is "the wrong scatterplot pairs are in the wrong places" for the last two pairs() calls.
>
> Thanks,
> Chris
>
> ################################################################
>
> # fake data
> xmat <- matrix(1:28, ncol=4)
> lim <- range(xmat)
>
> # what I expected
> pairs(xmat, xlim=lim, ylim=lim) # 4x4 matrix of scatterplots
> pairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:2) # 2x2 matrix of scatterplots: upper left
>
> # here comes trouble
> pairs(xmat, xlim=lim, ylim=lim, horInd=1:2) # 2x4 matrix of scatterplots: but not the top 2 rows (or bottom 2 rows)
> pairs(xmat, xlim=lim, ylim=lim, verInd=1:2) # 4x2 matrix of scatterplots: but not the left 2 columns (or right 2 columns)
>
>
> ###############################################################
>
>> sessionInfo()
> R version 3.5.0 (2018-04-23)
> Platform: x86_64-w64-mingw32/x64 (64-bit)
> Running under: Windows 7 x64 (build 7601) Service Pack 1
>
> Matrix products: default
>
> locale:
> [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
> [4] LC_NUMERIC=C                           LC_TIME=English_United States.1252
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
>
> loaded via a namespace (and not attached):
> [1] compiler_3.5.0 tools_3.5.0
> **********************************************************
> Electronic Mail is not secure, may not be read every day, and should not be used for urgent or sensitive issues
>
>
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Martin Maechler
>>>>> Gerrit Eichner
>>>>>     on Thu, 7 Jun 2018 09:03:46 +0200 writes:

    > Hi, Chris, had the same problem (and first thought it was
    > my fault), but there seems to be a typo in the code of
    > pairs.default. Below is a workaround.  Look for two
    > comments (starting with #####) in the code to see what I
    > have changed to make it work at least the way I'd expect
    > it in one of your examples.

    >   Hth -- Gerrit

> mypairs <- function (x, labels, panel = points, ...,
>      horInd = 1:nc, verInd = 1:nc,
>      lower.panel = panel, upper.panel = panel, diag.panel = NULL,
>      text.panel = textPanel, label.pos = 0.5 + has.diag/3, line.main = 3,
>      cex.labels = NULL, font.labels = 1, row1attop = TRUE, gap = 1,
>      log = "") {
>      if (doText <- missing(text.panel) || is.function(text.panel))
>          textPanel <- function(x = 0.5, y = 0.5, txt, cex, font) text(x,
>              y, txt, cex = cex, font = font)
>      localAxis <- function(side, x, y, xpd, bg, col = NULL, main,
>          oma, ...) {
>          xpd <- NA
>          if (side%%2L == 1L && xl[j])
>              xpd <- FALSE
>          if (side%%2L == 0L && yl[i])
>              xpd <- FALSE
>          if (side%%2L == 1L)
>              Axis(x, side = side, xpd = xpd, ...)
>          else Axis(y, side = side, xpd = xpd, ...)
>      }
>      localPlot <- function(..., main, oma, font.main, cex.main) plot(...)
>      localLowerPanel <- function(..., main, oma, font.main, cex.main) lower.panel(...)
>      localUpperPanel <- function(..., main, oma, font.main, cex.main) upper.panel(...)
>      localDiagPanel <- function(..., main, oma, font.main, cex.main) diag.panel(...)
>      dots <- list(...)
>      nmdots <- names(dots)
>      if (!is.matrix(x)) {
>          x <- as.data.frame(x)
>          for (i in seq_along(names(x))) {
>              if (is.factor(x[[i]]) || is.logical(x[[i]]))
>                  x[[i]] <- as.numeric(x[[i]])
>              if (!is.numeric(unclass(x[[i]])))
>                  stop("non-numeric argument to 'pairs'")
>          }
>      }
>      else if (!is.numeric(x))
>          stop("non-numeric argument to 'pairs'")
>      panel <- match.fun(panel)
>      if ((has.lower <- !is.null(lower.panel)) && !missing(lower.panel))
>          lower.panel <- match.fun(lower.panel)
>      if ((has.upper <- !is.null(upper.panel)) && !missing(upper.panel))
>          upper.panel <- match.fun(upper.panel)
>      if ((has.diag <- !is.null(diag.panel)) && !missing(diag.panel))
>          diag.panel <- match.fun(diag.panel)
>      if (row1attop) {
>          tmp <- lower.panel
>          lower.panel <- upper.panel
>          upper.panel <- tmp
>          tmp <- has.lower
>          has.lower <- has.upper
>          has.upper <- tmp
>      }
>      nc <- ncol(x)
>      if (nc < 2L)
>          stop("only one column in the argument to 'pairs'")
>      if (!all(horInd >= 1L && horInd <= nc))
>          stop("invalid argument 'horInd'")
>      if (!all(verInd >= 1L && verInd <= nc))
>          stop("invalid argument 'verInd'")
>      if (doText) {
>          if (missing(labels)) {
>              labels <- colnames(x)
>              if (is.null(labels))
>                  labels <- paste("var", 1L:nc)
>          }
>          else if (is.null(labels))
>              doText <- FALSE
>      }
>      oma <- if ("oma" %in% nmdots)
>          dots$oma
>      main <- if ("main" %in% nmdots)
>          dots$main
>      if (is.null(oma))
>          oma <- c(4, 4, if (!is.null(main)) 6 else 4, 4)
>      opar <- par(mfcol = c(length(horInd), length(verInd)),
> ##### Changed from mfrow to mfcol
>                  mar = rep.int(gap/2, 4), oma = oma)
>      on.exit(par(opar))
>      dev.hold()
>      on.exit(dev.flush(), add = TRUE)
>      xl <- yl <- logical(nc)
>      if (is.numeric(log))
>          xl[log] <- yl[log] <- TRUE
>      else {
>          xl[] <- grepl("x", log)
>          yl[] <- grepl("y", log)
>      }
>      for (j in if (row1attop) verInd else rev(verInd))
>       for (i in horInd) {
> ##### Exchanged i and j. (i used to be in
> ##### the outer and j in the inner loop!)
>          l <- paste0(ifelse(xl[j], "x", ""), ifelse(yl[i], "y", ""))
>          localPlot(x[, j], x[, i], xlab = "", ylab = "", axes = FALSE,
>              type = "n", ..., log = l)
>          if (i == j || (i < j && has.lower) || (i > j && has.upper)) {
>              box()
>              if (i == 1 && (!(j%%2L) || !has.upper || !has.lower))
>                  localAxis(1L + 2L * row1attop, x[, j], x[, i],
>                    ...)
>              if (i == nc && (j%%2L || !has.upper || !has.lower))
>                  localAxis(3L - 2L * row1attop, x[, j], x[, i],
>                    ...)
>              if (j == 1 && (!(i%%2L) || !has.upper || !has.lower))
>                  localAxis(2L, x[, j], x[, i], ...)
>              if (j == nc && (i%%2L || !has.upper || !has.lower))
>                  localAxis(4L, x[, j], x[, i], ...)
>              mfg <- par("mfg")
>              if (i == j) {
>                  if (has.diag)
>                    localDiagPanel(as.vector(x[, i]), ...)
>                  if (doText) {
>                    par(usr = c(0, 1, 0, 1))
>                    if (is.null(cex.labels)) {
>                      l.wid <- strwidth(labels, "user")
>                      cex.labels <- max(0.8, min(2, 0.9/max(l.wid)))
>                    }
>                    xlp <- if (xl[i])
>                      10^0.5
>                    else 0.5
>                    ylp <- if (yl[j])
>                      10^label.pos
>                    else label.pos
>                    text.panel(xlp, ylp, labels[i], cex = cex.labels,
>                      font = font.labels)
>                  }
>              }
>              else if (i < j)
>                  localLowerPanel(as.vector(x[, j]), as.vector(x[,
>                    i]), ...)
>              else localUpperPanel(as.vector(x[, j]), as.vector(x[,
>                  i]), ...)
>              if (any(par("mfg") != mfg))
>                  stop("the 'panel' function made a new plot")
>          }
>          else par(new = FALSE)
>      }
>      if (!is.null(main)) {
>          font.main <- if ("font.main" %in% nmdots)
>              dots$font.main
>          else par("font.main")
>          cex.main <- if ("cex.main" %in% nmdots)
>              dots$cex.main
>          else par("cex.main")
>          mtext(main, 3, line.main, outer = TRUE, at = 0.5, cex = cex.main,
>              font = font.main)
>      }
>      invisible(NULL)
> }
>
>
>
> ## Example:
>
> mypairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:4)

Thank you, Chris, for the report and
Gerrit for your proposed fix !!

It looks good to me,  but I will test some more (also with
'row1attop=FALSE')  before committing the bug fix.

Best regards,

Martin Maechler
ETH Zurich and R Core Team

> Am 06.06.2018 um 23:55 schrieb Andrews, Chris:
> >
> > After making scatterplot matrix, I determined I only needed the first 2 columns of the matrix so I added verInd=1:2 to my pairs() call.  However, it did not turn out as I expected.
> >
> > Perhaps the attached pdf of the example code will make it through.  If not, my description is "the wrong scatterplot pairs are in the wrong places" for the last two pairs() calls.
> >
> > Thanks,
> > Chris
> >
> > ################################################################
> >
> > # fake data
> > xmat <- matrix(1:28, ncol=4)
> > lim <- range(xmat)
> >
> > # what I expected
> > pairs(xmat, xlim=lim, ylim=lim) # 4x4 matrix of scatterplots
> > pairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:2) # 2x2 matrix of scatterplots: upper left
> >
> > # here comes trouble
> > pairs(xmat, xlim=lim, ylim=lim, horInd=1:2) # 2x4 matrix of scatterplots: but not the top 2 rows (or bottom 2 rows)
> > pairs(xmat, xlim=lim, ylim=lim, verInd=1:2) # 4x2 matrix of scatterplots: but not the left 2 columns (or right 2 columns)
> >
> >
> > ###############################################################
> >
> >> sessionInfo()
> > R version 3.5.0 (2018-04-23)
> > Platform: x86_64-w64-mingw32/x64 (64-bit)
> > Running under: Windows 7 x64 (build 7601) Service Pack 1
> >
> > Matrix products: default
> >
> > locale:
> > [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
> > [4] LC_NUMERIC=C                           LC_TIME=English_United States.1252
> >
> > attached base packages:
> > [1] stats     graphics  grDevices utils     datasets  methods   base
> >
> > loaded via a namespace (and not attached):
> > [1] compiler_3.5.0 tools_3.5.0
> > **********************************************************

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Martin Maechler
>>>>> Martin Maechler
>>>>>     on Thu, 7 Jun 2018 18:35:48 +0200 writes:

>>>>> Gerrit Eichner
>>>>>     on Thu, 7 Jun 2018 09:03:46 +0200 writes:

    >> Hi, Chris, had the same problem (and first thought it was
    >> my fault), but there seems to be a typo in the code of
    >> pairs.default. Below is a workaround.  Look for two
    >> comments (starting with #####) in the code to see what I
    >> have changed to make it work at least the way I'd expect
    >> it in one of your examples.

    >> Hth -- Gerrit


> > mypairs <- function (x, labels, panel = points, ...,
> >      horInd = 1:nc, verInd = 1:nc,
> >      lower.panel = panel, upper.panel = panel, diag.panel = NULL,
> >      text.panel = textPanel, label.pos = 0.5 + has.diag/3, line.main = 3,
> >      cex.labels = NULL, font.labels = 1, row1attop = TRUE, gap = 1,
> >      log = "") {
> >      if (doText <- missing(text.panel) || is.function(text.panel))
> >          textPanel <- function(x = 0.5, y = 0.5, txt, cex, font) text(x,
> >              y, txt, cex = cex, font = font)
> >      localAxis <- function(side, x, y, xpd, bg, col = NULL, main,
> >          oma, ...) {
> >          xpd <- NA
> >          if (side%%2L == 1L && xl[j])
> >              xpd <- FALSE
> >          if (side%%2L == 0L && yl[i])
> >              xpd <- FALSE
> >          if (side%%2L == 1L)
> >              Axis(x, side = side, xpd = xpd, ...)
> >          else Axis(y, side = side, xpd = xpd, ...)
> >      }
> >      localPlot <- function(..., main, oma, font.main, cex.main) plot(...)
> >      localLowerPanel <- function(..., main, oma, font.main, cex.main) lower.panel(...)
> >      localUpperPanel <- function(..., main, oma, font.main, cex.main) upper.panel(...)
> >      localDiagPanel <- function(..., main, oma, font.main, cex.main) diag.panel(...)
> >      dots <- list(...)
> >      nmdots <- names(dots)
> >      if (!is.matrix(x)) {
> >          x <- as.data.frame(x)
> >          for (i in seq_along(names(x))) {
> >              if (is.factor(x[[i]]) || is.logical(x[[i]]))
> >                  x[[i]] <- as.numeric(x[[i]])
> >              if (!is.numeric(unclass(x[[i]])))
> >                  stop("non-numeric argument to 'pairs'")
> >          }
> >      }
> >      else if (!is.numeric(x))
> >          stop("non-numeric argument to 'pairs'")
> >      panel <- match.fun(panel)
> >      if ((has.lower <- !is.null(lower.panel)) && !missing(lower.panel))
> >          lower.panel <- match.fun(lower.panel)
> >      if ((has.upper <- !is.null(upper.panel)) && !missing(upper.panel))
> >          upper.panel <- match.fun(upper.panel)
> >      if ((has.diag <- !is.null(diag.panel)) && !missing(diag.panel))
> >          diag.panel <- match.fun(diag.panel)
> >      if (row1attop) {
> >          tmp <- lower.panel
> >          lower.panel <- upper.panel
> >          upper.panel <- tmp
> >          tmp <- has.lower
> >          has.lower <- has.upper
> >          has.upper <- tmp
> >      }
> >      nc <- ncol(x)
> >      if (nc < 2L)
> >          stop("only one column in the argument to 'pairs'")
> >      if (!all(horInd >= 1L && horInd <= nc))
> >          stop("invalid argument 'horInd'")
> >      if (!all(verInd >= 1L && verInd <= nc))
> >          stop("invalid argument 'verInd'")
> >      if (doText) {
> >          if (missing(labels)) {
> >              labels <- colnames(x)
> >              if (is.null(labels))
> >                  labels <- paste("var", 1L:nc)
> >          }
> >          else if (is.null(labels))
> >              doText <- FALSE
> >      }
> >      oma <- if ("oma" %in% nmdots)
> >          dots$oma
> >      main <- if ("main" %in% nmdots)
> >          dots$main
> >      if (is.null(oma))
> >          oma <- c(4, 4, if (!is.null(main)) 6 else 4, 4)
> >      opar <- par(mfcol = c(length(horInd), length(verInd)),
> > ##### Changed from mfrow to mfcol
> >                  mar = rep.int(gap/2, 4), oma = oma)
> >      on.exit(par(opar))
> >      dev.hold()
> >      on.exit(dev.flush(), add = TRUE)
> >      xl <- yl <- logical(nc)
> >      if (is.numeric(log))
> >          xl[log] <- yl[log] <- TRUE
> >      else {
> >          xl[] <- grepl("x", log)
> >          yl[] <- grepl("y", log)
> >      }
> >      for (j in if (row1attop) verInd else rev(verInd))
> >       for (i in horInd) {
> > ##### Exchanged i and j. (i used to be in
> > ##### the outer and j in the inner loop!)
> >          l <- paste0(ifelse(xl[j], "x", ""), ifelse(yl[i], "y", ""))
> >          localPlot(x[, j], x[, i], xlab = "", ylab = "", axes = FALSE,
> >              type = "n", ..., log = l)
> >          if (i == j || (i < j && has.lower) || (i > j && has.upper)) {
> >              box()
> >              if (i == 1 && (!(j%%2L) || !has.upper || !has.lower))
> >                  localAxis(1L + 2L * row1attop, x[, j], x[, i],
> >                    ...)
> >              if (i == nc && (j%%2L || !has.upper || !has.lower))
> >                  localAxis(3L - 2L * row1attop, x[, j], x[, i],
> >                    ...)
> >              if (j == 1 && (!(i%%2L) || !has.upper || !has.lower))
> >                  localAxis(2L, x[, j], x[, i], ...)
> >              if (j == nc && (i%%2L || !has.upper || !has.lower))
> >                  localAxis(4L, x[, j], x[, i], ...)
> >              mfg <- par("mfg")
> >              if (i == j) {
> >                  if (has.diag)
> >                    localDiagPanel(as.vector(x[, i]), ...)
> >                  if (doText) {
> >                    par(usr = c(0, 1, 0, 1))
> >                    if (is.null(cex.labels)) {
> >                      l.wid <- strwidth(labels, "user")
> >                      cex.labels <- max(0.8, min(2, 0.9/max(l.wid)))
> >                    }
> >                    xlp <- if (xl[i])
> >                      10^0.5
> >                    else 0.5
> >                    ylp <- if (yl[j])
> >                      10^label.pos
> >                    else label.pos
> >                    text.panel(xlp, ylp, labels[i], cex = cex.labels,
> >                      font = font.labels)
> >                  }
> >              }
> >              else if (i < j)
> >                  localLowerPanel(as.vector(x[, j]), as.vector(x[,
> >                    i]), ...)
> >              else localUpperPanel(as.vector(x[, j]), as.vector(x[,
> >                  i]), ...)
> >              if (any(par("mfg") != mfg))
> >                  stop("the 'panel' function made a new plot")
> >          }
> >          else par(new = FALSE)
> >      }
> >      if (!is.null(main)) {
> >          font.main <- if ("font.main" %in% nmdots)
> >              dots$font.main
> >          else par("font.main")
> >          cex.main <- if ("cex.main" %in% nmdots)
> >              dots$cex.main
> >          else par("cex.main")
> >          mtext(main, 3, line.main, outer = TRUE, at = 0.5, cex = cex.main,
> >              font = font.main)
> >      }
> >      invisible(NULL)
> > }
> >
> >
> >
> > ## Example:
> >
> > mypairs(xmat, xlim=lim, ylim=lim, verInd=1:2, horInd=1:4)
>
> Thank you, Chris, for the report and
> Gerrit for your proposed fix !!
>
> It looks good to me,  but I will test some more (also with
> 'row1attop=FALSE')  before committing the bug fix.

and there, another change was needed:  Instead of your

    for (j in if (row1attop) verInd else rev(verInd))
        for (i in horInd) {

we do now need

    for(j in verInd)
        for(i in if(row1attop) horInd else rev(horInd)) {

and the difference is of course only relevant for the
non-default  'row1attop = FALSE'

  (which some graphic experts argue to be clearly *better* than the default,
   as only in that case,  the upper and lower triangles of the
   matrix are nicely "mirrors of each other", and that is also
   the reason why  lattice::splom()  uses the equivalent of
   'row1attop=FALSE')

I will commit the change to R-devel today - and intend to port
to R-patched in time to make it into the upcoming R 3.5.1.

Thank you once more !
Martin

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Martin Maechler
>>>>> Martin Maechler
>>>>>     on Fri, 8 Jun 2018 11:13:24 +0200 writes:

[..........]

    >> Thank you, Chris, for the report and
    >> Gerrit for your proposed fix !!
    >>
    >> It looks good to me,  but I will test some more (also with
    >> 'row1attop=FALSE')  before committing the bug fix.

    > and there, another change was needed:  Instead of your

    > for (j in if (row1attop) verInd else rev(verInd))
    >    for (i in horInd) {

    > we do now need

    > for(j in verInd)
    >    for(i in if(row1attop) horInd else rev(horInd)) {

    > and the difference is of course only relevant for the
    > non-default  'row1attop = FALSE'

    > (which some graphic experts argue to be clearly *better* than the default,
    > as only in that case,  the upper and lower triangles of the
    > matrix are nicely "mirrors of each other", and that is also
    > the reason why  lattice::splom()  uses the equivalent of
    > 'row1attop=FALSE')

    > I will commit the change to R-devel today - and intend to port
    > to R-patched in time to make it into the upcoming R 3.5.1.

Well, as I find, there are more bugs there, if you are using
'horInd' and 'verInd' creatively:

In a nice pairs(), the axis ticks (and their labels (numbers))
are always "on the outside" of the scatterplot matrix, and
nicely alternating.  This is not the case unfortunately, when using
 horInd or verInd which are *not* of the form p1:p2 (p1 <= p2)

==> even more changes are needed to make these cases "nice",
or  should we *require* horInd and verInd to be of that form??

This would not be back-compatible, but than such cases have been
"wrong" really in all versions of R anyway, *and*  at least be
reordering the matrix/data.frame columns, the restriction of

    (hor|ver)Ind =  p1:p2 (p1 <= p2)

would seem acceptable, would it ?

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Gerrit Eichner
Am 08.06.2018 um 12:02 schrieb Martin Maechler:

>>>>>> Martin Maechler
>>>>>>      on Fri, 8 Jun 2018 11:13:24 +0200 writes:
>
> [..........]
>
>      >> Thank you, Chris, for the report and
>      >> Gerrit for your proposed fix !!
>      >>
>      >> It looks good to me,  but I will test some more (also with
>      >> 'row1attop=FALSE')  before committing the bug fix.
>
>      > and there, another change was needed:  Instead of your
>
>      > for (j in if (row1attop) verInd else rev(verInd))
>      >    for (i in horInd) {
>
>      > we do now need
>
>      > for(j in verInd)
>      >    for(i in if(row1attop) horInd else rev(horInd)) {
>
>      > and the difference is of course only relevant for the
>      > non-default  'row1attop = FALSE'
>
>      > (which some graphic experts argue to be clearly *better* than the default,
>      > as only in that case,  the upper and lower triangles of the
>      > matrix are nicely "mirrors of each other", and that is also
>      > the reason why  lattice::splom()  uses the equivalent of
>      > 'row1attop=FALSE')
>
>      > I will commit the change to R-devel today - and intend to port
>      > to R-patched in time to make it into the upcoming R 3.5.1.
>
> Well, as I find, there are more bugs there, if you are using
> 'horInd' and 'verInd' creatively:
>
> In a nice pairs(), the axis ticks (and their labels (numbers))
> are always "on the outside" of the scatterplot matrix, and
> nicely alternating.  This is not the case unfortunately, when using
>   horInd or verInd which are *not* of the form p1:p2 (p1 <= p2)
>
> ==> even more changes are needed to make these cases "nice",

Well, the *shown* axis ticks and labels do nicely alternate if
(hor|ver)Ind = p1:p2 (p1 <= p2) is fulfilled, but not all of
the axis ticks and labels, which one *might* wish to see, are
currently drawn anyway ... I would consider changes which "heal"
this as more interesting than solving this problem in full
generality, i.e., in cases of creative use of (hor|ver)Ind.
However, I don't think it's urgent, at all.


> or  should we *require* horInd and verInd to be of that form??
>
> This would not be back-compatible, but than such cases have been
> "wrong" really in all versions of R anyway, *and*  at least be
> reordering the matrix/data.frame columns, the restriction of
>
>      (hor|ver)Ind =  p1:p2 (p1 <= p2)
>
> would seem acceptable, would it ?
>

I could live very well with that requirement (while breaking
back-compatibility), because from my point of view a "creative"
use of 'horInd' and 'verInd' violating (hor|ver)Ind = p1:p2
(p1 <= p2) won't occur often.

On the other hand, why forcing (hor|ver)Ind = p1:p2 (p1 <= p2)?
If people violated it "they get what they deserve". ;-)

Btw, 'horInd' and 'verInd' sort of exchange their meaning if
row1attop = FALSE, but I this can be explained by the "work flow":
First, (hor|ver)Ind are used to select the respective rows and
columns from the full paris-plot, and then, row1attop is used
when the results are drawn. I think this is sensible.

  Regards  --  Gerrit

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: verInd= and HorInd= arguments to pairs() function

Martin Maechler
>>>>> Gerrit Eichner
>>>>>     on Fri, 8 Jun 2018 12:55:31 +0200 writes:

    > Am 08.06.2018 um 12:02 schrieb Martin Maechler:
    >>>>>>> Martin Maechler
    >>>>>>> on Fri, 8 Jun 2018 11:13:24 +0200 writes:
    >>
    >> [..........]
    >>
    >> >> Thank you, Chris, for the report and
    >> >> Gerrit for your proposed fix !!
    >> >>
    >> >> It looks good to me,  but I will test some more (also with
    >> >> 'row1attop=FALSE')  before committing the bug fix.
    >>
    >> > and there, another change was needed:  Instead of your
    >>
    >> > for (j in if (row1attop) verInd else rev(verInd))
    >> >    for (i in horInd) {
    >>
    >> > we do now need
    >>
    >> > for(j in verInd)
    >> >    for(i in if(row1attop) horInd else rev(horInd)) {
    >>
    >> > and the difference is of course only relevant for the
    >> > non-default  'row1attop = FALSE'
    >>
    >> > (which some graphic experts argue to be clearly *better* than the default,
    >> > as only in that case,  the upper and lower triangles of the
    >> > matrix are nicely "mirrors of each other", and that is also
    >> > the reason why  lattice::splom()  uses the equivalent of
    >> > 'row1attop=FALSE')
    >>
    >> > I will commit the change to R-devel today - and intend to port
    >> > to R-patched in time to make it into the upcoming R 3.5.1.
    >>
    >> Well, as I find, there are more bugs there, if you are using
    >> 'horInd' and 'verInd' creatively:
    >>
    >> In a nice pairs(), the axis ticks (and their labels (numbers))
    >> are always "on the outside" of the scatterplot matrix, and
    >> nicely alternating.  This is not the case unfortunately, when using
    >> horInd or verInd which are *not* of the form p1:p2 (p1 <= p2)
    >>
    >> ==> even more changes are needed to make these cases "nice",

    > Well, the *shown* axis ticks and labels do nicely alternate if
    > (hor|ver)Ind = p1:p2 (p1 <= p2) is fulfilled, but not all of
    > the axis ticks and labels, which one *might* wish to see, are
    > currently drawn anyway ... I would consider changes which "heal"
    > this as more interesting than solving this problem in full
    > generality, i.e., in cases of creative use of (hor|ver)Ind.
    > However, I don't think it's urgent, at all.


    >> or  should we *require* horInd and verInd to be of that form??
    >>
    >> This would not be back-compatible, but than such cases have been
    >> "wrong" really in all versions of R anyway, *and*  at least be
    >> reordering the matrix/data.frame columns, the restriction of
    >>
    >> (hor|ver)Ind =  p1:p2 (p1 <= p2)
    >>
    >> would seem acceptable, would it ?
    >>

    > I could live very well with that requirement (while breaking
    > back-compatibility), because from my point of view a "creative"
    > use of 'horInd' and 'verInd' violating (hor|ver)Ind = p1:p2
    > (p1 <= p2) won't occur often.

    > On the other hand, why forcing (hor|ver)Ind = p1:p2 (p1 <= p2)?
    > If people violated it "they get what they deserve". ;-)

    > Btw, 'horInd' and 'verInd' sort of exchange their meaning if
    > row1attop = FALSE, but I this can be explained by the "work flow":
    > First, (hor|ver)Ind are used to select the respective rows and
    > columns from the full paris-plot, and then, row1attop is used
    > when the results are drawn. I think this is sensible.

Thank you; and yes indeed, and I was not going to change that.

In fact, I've found a relatively nice solution now, which does
*not* restrict the settings of '{hor,ver}Ind' and fixes all
problems mentioned,  quite back compatibly, and in some sense
perfectly labeling the axes.

==> Committed to R-devel svn c74871  a few minutes ago.

Martin

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.