Re: [Rd] Should c(..., recursive = TRUE) and unlist(x, recursive = TRUE) recurse into expression vectors?

2024-04-27 Thread Mikael Jagan




On 2024-04-27 10:53 am, Mikael Jagan wrote:

Reading the body of function 'AnswerType' in bind.c, called from 'do_c'
and 'do_unlist', I notice that EXPRSXP and VECSXP are handled identically
in the  recurse = TRUE  case.

A corollary is that  c(recursive = TRUE)  and  unlist(recursive = TRUE)
treat expression vectors like  expression(a, b)  as lists of symbols and
calls.  And since they treat symbols and calls as lists of length 1, we
see:

  > x <- expression(a, b); y <- expression(c, d)
  > c(x, y)
expression(a, b, c, d)
  > c(x, y, recursive = TRUE)
[[1]]
a

[[2]]
b

[[3]]
c

[[4]]
d

My expectation based on the documentation in help("c") and help("unlist")
is that those functions would recurse into lists and pairlists, but _not_
into expression vectors.

  recursive: logical.  If 'recursive = TRUE', the function recursively
descends through lists (and pairlists) combining all their
elements into a vector.

  recursive: logical.  Should unlisting be applied to list components of
'x'?

My feeling is that either:

(1) the behaviour should change, so that both calls to 'c' above give
  the result of type "expression".
(2) the documentation should change to say that expression vectors are
  handled as lists in the recursive case.

Option (2) won't break anything but is a bit awkward because it means
that a type "higher" in the documented hierarchy (... < list < expression)
is coerced to a lower type.



Er - this last comment about Option (2) being awkward can be ignored.  The
expression vector is not itself coerced to a list.  Rather, its non-vector
components are treated as lists of length 1.  And that's well-documented.

If anything, Option (1) is awkward as it would treat two types of generic
vectors, list and expression, asymmetrically ...

I can submit a patch implementing Option (2) in a few days to allow for
comments if any.

Mikael


I'll add here that, confusingly, help("expression") says: "an object of
mode 'expression' is a list".  I understand the author's intent (lists and
expression vectors differ only in the 'type' field of the SEXP header) but
I wonder if substituting "list" with "generic vector" there would cause
less confusion ... ?

Mikael


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Should c(..., recursive = TRUE) and unlist(x, recursive = TRUE) recurse into expression vectors?

2024-04-27 Thread Mikael Jagan

Reading the body of function 'AnswerType' in bind.c, called from 'do_c'
and 'do_unlist', I notice that EXPRSXP and VECSXP are handled identically
in the  recurse = TRUE  case.

A corollary is that  c(recursive = TRUE)  and  unlist(recursive = TRUE)
treat expression vectors like  expression(a, b)  as lists of symbols and
calls.  And since they treat symbols and calls as lists of length 1, we
see:

> x <- expression(a, b); y <- expression(c, d)
> c(x, y)
expression(a, b, c, d)
> c(x, y, recursive = TRUE)
[[1]]
a

[[2]]
b

[[3]]
c

[[4]]
d

My expectation based on the documentation in help("c") and help("unlist")
is that those functions would recurse into lists and pairlists, but _not_
into expression vectors.

recursive: logical.  If 'recursive = TRUE', the function recursively
  descends through lists (and pairlists) combining all their
  elements into a vector.

recursive: logical.  Should unlisting be applied to list components of
  'x'?

My feeling is that either:

(1) the behaviour should change, so that both calls to 'c' above give
the result of type "expression".
(2) the documentation should change to say that expression vectors are
handled as lists in the recursive case.

Option (2) won't break anything but is a bit awkward because it means
that a type "higher" in the documented hierarchy (... < list < expression)
is coerced to a lower type.

I'll add here that, confusingly, help("expression") says: "an object of
mode 'expression' is a list".  I understand the author's intent (lists and
expression vectors differ only in the 'type' field of the SEXP header) but
I wonder if substituting "list" with "generic vector" there would cause
less confusion ... ?

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[R-pkg-devel] Matrix 1.7-0 to be released in March with ABI-breaking SuiteSparse update

2024-02-12 Thread Mikael Jagan

Dear users and binary repository maintainers,

We are preparing Matrix version 1.7-0 for CRAN submission on March 11, ahead
of the spring release of R version 4.4.0.  The only significant change from
Matrix 1.6-5 is an update of the internal SuiteSparse libraries
(5.10.1 -> 7.6.0).  Unfortunately, the old and new SuiteSparse versions are 
binary incompatible, hence so too will be the old and new Matrix versions.


A corollary is that users and binary repository maintainers switching between
Matrix < 1.7-0 and Matrix >= 1.7-0 must rebuild _from sources_ packages that
link Matrix:

> tools::package_dependencies("Matrix", which = "LinkingTo", reverse = 
TRUE)[[1L]]
 [1] "ahMLE"   "bayesWatch"  "cplm"
 [4] "GeneralizedWendland" "geostatsp"   "irlba"
 [7] "lme4""mcmcsae" "OpenMx"
[10] "PRIMME"  "PUlasso" "robustlmm"
[13] "spGARCH" "TMB" "bcSeq"

For users, that means doing, e.g.,

install.packages("lme4", type = "source")

but an alternative for Windows and macOS users without the required tools is

oo <- options(repos = "https://cran.r-project.org/;)
install.packages("Matrix")
install.packages("lme4")
options(oo)

where we trust CRAN to provide binaries compatible with the latest Matrix
version (because we notify CRAN upon submission about required rebuilds).
Once other repositories react with rebuilds, they can be used instead of
CRAN.

Our reverse dependency checks (and history, intuition, ...) show that most
problems (caught segfaults in this case) can be traced to a binary incompatible
lme4 and not to one of the other packages linking Matrix.  Still, we recommend
rebuilds for all 15 packages.

Maintainers of packages that link Matrix can implement an .onLoad test for
possible binary incompatibility by comparing the value of

if (utils::packageVersion("Matrix") >= "1.6.2")
Matrix::Matrix.Version()[["abi"]]
else numeric_version("0")

at install time and at load time, warning the user if the values differ.
But please do look at the above and not at packageVersion("Matrix") directly,
as the ABI version is incremented less often than the package version.

Mikael {on behalf of citation("Matrix")$author}

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [Rd] Matrix 1.6.2+ versus Matrix 1.6.2-

2023-11-22 Thread Mikael Jagan

Naras,

Thanks.  I'm a bit confused, because Rmosek does not declare Matrix as a
dependency:

> tools::package_dependencies("Rmosek", which = "all")[[1L]]
[1] "pkgbuild"

nor does it contain code needing compilation:

> packageDescription("Rmosek", fields="NeedsCompilation")
[1] "no"

Can you explain the nature of the dependency and how I can reproduce your
output?  Is an _external_ library somehow linking Matrix ... ?

Note that the 3 removed entry points were unused by all reverse LinkingTo
on CRAN and BioC at the time that Matrix 1.6-2 was released.  We can
suggest replacements (probably off list; I don't know that R-devel is the
right forum) but only if we are able to see the code being compiled ...

Mikael

> Package Rmosek compiles fine using Matrix versions 1.6.2- but not with
> anything beyond Matrix 1.6.2.  (FYI, Rmosek provides R interfaces to the
> excellent MOSEK solver; academic licenses are free.)
>
> Here is the error message:
>
> rmsk_obj_matrices.cc:50:9: error: use of undeclared identifier 
'Matrix_isclass_Csparse'

> 50 | if (Matrix_isclass_Csparse(val)) {
>| ^
> rmsk_obj_matrices.cc:171:9: error: use of undeclared identifier 
'Matrix_isclass_triplet'

>171 | if (Matrix_isclass_triplet(val)) {
>| ^
> rmsk_obj_matrices.cc:225:24: error: use of undeclared identifier 
'M_chm_triplet_to_SEXP'
>225 |   matrixhandle.protect(M_chm_triplet_to_SEXP(tmp, 0, 0, 0, NULL, 
R_NilValue));

>
> These API entry points are no longer in the recent headers. My quick
> examination shows that the first two seem like mostly R API stuff and so
> can be copied over to Rmosek easily but the last one looks more involved
> in my cursory examination.
>
> I was going to let the author of Rmosek know, but I do not see any
> mention of these API entries going away in the NEWS for Matrix.
>
> Would be good to point the author to a suggested approach or even
> provide the beginnings of a fix. Any thoughts, particularly by Matrix
> authors (Martin, Mikael)?
>
> Thanks in advance.
>
> -Naras

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] R-4.3 version list.files function could not work correctly in chinese

2023-11-22 Thread Mikael Jagan

FWIW, a user on Stack Overflow just reported the same issue with list.files
running R 4.3.z on Windows.  They do not observe the issue running R-devel,
with Tomas' patch (r84960).  It is still the case that their file names did
not exceed 260 wide characters.

https://stackoverflow.com/q/77527167/12685768

Mikael

On 2023-08-17 6:00 am, r-devel-requ...@r-project.org wrote:

Message: 5
Date: Wed, 16 Aug 2023 16:00:13 +0200
From: Tomas Kalibera
To: Ivan Krylov
Cc:"r-devel@r-project.org"  
Subject: Re: [Rd]  R-4.3 version list.files function could not work
correctly in chinese
Message-ID:<21e91609-85b2-103b-8e23-12eadff62...@gmail.com>
Content-Type: text/plain; charset="utf-8"; Format="flowed"


On 8/16/23 13:22, Ivan Krylov wrote:

On Wed, 16 Aug 2023 09:42:09 +0200
Tomas Kalibera  wrote:


Fixed in R-devel (84960). Please let me know if you see any problem
with the fix.

Thank you for implementing the fix! I gave 叶月光 the link to the
GitHub Action build of the r84960 installer.

Thanks and thanks for looking at the change.

I'm worried that 叶月光 was seeing FindNextFileA fail for a different
reason (all the examples given at the Capital of Statistics forum
seemed to use less than 256/4 = 64 characters per file name...), but
maybe this won't reappear with the switch to FindNextFileW. If this
keeps happening, it might be worth producing a warning when
FindNextFileW() fails with an unexpected GetLastError() value.

I've added a warning to R-devel when list.files() on Windows stops
listing a directory due to an error.

There is probably not more we can do unless there is a revised bug
report of the original problem.


fs::dir_fs() uses NtQueryDirectoryFile() and WideCharToMultiByte()
instead of FindNextFileW() and wcstombs(), but maybe this shouldn't
matter. In particular, both list.files() and fs::dir_fs() would fail
given a file name that cannot be represented in UTF-8 (invalid UTF-16
surrogate pairs?)

Right, R only support file names that are valid strings, this assumption
is present at many places in the code, so it is fine/consistent to be
here as well. The choice of opendir/readdir in R was probably motivated
by minimization of platform-specific code.

Best
Tomas


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [R-pkg-devel] Note to repository maintainers about ABI change in Matrix 1.6-2

2023-11-11 Thread Mikael Jagan




On 2023-11-10 5:04 pm, Mikael Jagan wrote:

For repositories != CRAN:

Matrix 1.6-2 was released on Nov 8.  Due to an ABI change, repositories
maintaining R package binaries should ensure that binaries for the first
order reverse LinkingTo of Matrix are rebuilt under Matrix 1.6-2:


  > db <- available.packages(repos = "https://cran.r-project.org/;)
  > tools::package_dependencies("Matrix", db = db, which = "LinkingTo", reverse 
=
TRUE)[[1L]]
   [1] "ahMLE"   "bayesWatch"  "cplm"
   [4] "GeneralizedWendland" "geostatsp"   "hibayes"
   [7] "irlba"   "lme4""mcmcsae"
[10] "OpenMx"  "PRIMME"  "robustlmm"
[13] "spGARCH" "TMB"



The following additional packages were found to have stale SClassExtension
objects cached in their namespaces:

MatrixModels, SeuratObject, softImpute

and so their binaries should be rebuilt also.

Mikael



Typically, ABI changes occur only rarely, when Matrix updates the internal
SuiteSparse libraries and _those_ libraries change _their_ ABI.  This case
is an exception: we discovered that certain function prototypes in our
headers were inconsistent with corresponding prototypes in the SuiteSparse
headers, and the "consistent" prototypes were not binary compatible.

It is for this reason (and others) that Matrix has begun versioning its ABI,
as I announced in an earlier thread on R-SIG-Mac:

  https://stat.ethz.ch/pipermail/r-sig-mac/2023-October/014890.html

That (in addition to future, more proactive announcements on mailing lists)
should allow repository maintainers to adapt sooner going forward.

Mikael


__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


[R-pkg-devel] Note to repository maintainers about ABI change in Matrix 1.6-2

2023-11-10 Thread Mikael Jagan

For repositories != CRAN:

Matrix 1.6-2 was released on Nov 8.  Due to an ABI change, repositories
maintaining R package binaries should ensure that binaries for the first
order reverse LinkingTo of Matrix are rebuilt under Matrix 1.6-2:


> db <- available.packages(repos = "https://cran.r-project.org/;)
> tools::package_dependencies("Matrix", db = db, which = "LinkingTo", reverse = 
TRUE)[[1L]]

 [1] "ahMLE"   "bayesWatch"  "cplm"
 [4] "GeneralizedWendland" "geostatsp"   "hibayes"
 [7] "irlba"   "lme4""mcmcsae"
[10] "OpenMx"  "PRIMME"  "robustlmm"
[13] "spGARCH" "TMB"


Typically, ABI changes occur only rarely, when Matrix updates the internal
SuiteSparse libraries and _those_ libraries change _their_ ABI.  This case
is an exception: we discovered that certain function prototypes in our
headers were inconsistent with corresponding prototypes in the SuiteSparse
headers, and the "consistent" prototypes were not binary compatible.

It is for this reason (and others) that Matrix has begun versioning its ABI,
as I announced in an earlier thread on R-SIG-Mac:

https://stat.ethz.ch/pipermail/r-sig-mac/2023-October/014890.html

That (in addition to future, more proactive announcements on mailing lists)
should allow repository maintainers to adapt sooner going forward.

Mikael

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?

2023-11-09 Thread Mikael Jagan




On 2023-11-09 3:13 am, Martin Maechler wrote:

Mikael Jagan
 on Wed, 8 Nov 2023 11:13:18 -0500 writes:


 > So, to summarize, the open questions are:
 > (1) Should as.complex(NA_character_) give complex(r=NA_real_, i=0)
 > instead of NA_complex_?

 > (2) Should the first argument in c(NA, x) and c(NA_integer_, x),
 > where typeof(x) == "complex", be promoted to complex(r=NA_real_, i=0)
 > instead of NA_complex_?

 > My opinions:

 > (1) No.  The imaginary part of the result of parsing the strings "i",
 > "+i", and "-i" can be nonzero.
 > Consider, e.g., Im(eval(str2lang("0+1i"))) and Im(as.complex("0+1i")).
 > If NA_character_ means "a string with unknown content", then we should
 > not assume that the string is parsed as a real number.

 > (2) Yes.  I'd very much like to preserve the identity of c(Im(NA), Im(x))
 > and Im(c(NA, x)) for atomic (excluding raw, character) vectors 'x'.

 > And while typing this response I noticed the following in current 
R-devel and
 > current R-patched:

 >> 0+1i
 > [1] 0+1i
 >> 1i
 > [1] 0+1i
 >> as.complex("0+1i")
 > [1] 0+1i
 >> as.complex("1i")
 > [1] NA
 > Warning message:
 > NAs introduced by coercion

 > That warning seems wrong to me ...

Well, actually, as we now have had the parser  accept
1i or 7i, 3.14i etc
I think  that it's not the *warning* that is wrong,
but rather the *result* :



Indeed.  I realized immediately that I had mistyped, and hoped that readers
would understand what I meant.  Yes, as.complex("1i") ought to give 1i and
_not_ NA.

Mikael


Why should   as.complex("1i")  be different  from  one of these?


1i

[1] 0+1i

str2lang("1i")

[1] 0+1i

scan(textConnection("1i"), complex())

Read 1 item
[1] 0+1i





 > Mikael

 > On 2023-11-07 6:00 am, r-devel-requ...@r-project.org wrote:
 >>>>>>> Michael Chirico
 >>>>>>> on Mon, 6 Nov 2023 23:18:40 -0800 writes:
 >> > Thanks Martin. My hang-up was not on what the outcome of 
as.complex(NA)
 >> > should be, but rather, how I should read code like c(x, y) generally. 
Till
 >> > now, I have thought of it like 'c(x, y)' is c(as(x, typeof(y)), y)` 
when
 >> > "type(y) > type(x)". Basically in my mind, "coercion" in R <->
 >> > as.(.) (or coerceVector() in C).
 >>
 >> > So I tracked down the source (which admittedly has been this way for 
much
 >> > longer than the present discussion) to see what exactly c() is doing 
in
 >> > this case:
 >>
 >> 
>https://github.com/r-devel/r-svn/blob/71e7480b07767f3b7d5c45a4247959aa4d83d910/src/main/bind.c#L418-L425
 >>
 >> > And indeed! It's not "coercion" in the sense I just described... 
there's a
 >> > branch for the 'x == NA_LOGICAL' case to_convert_  to NA_complex_.
 >>
 >> Yes; "of course" ... still, I did not answer your main question,
 >> as you did ask +/-  if  c() should not get an adjustment to the
 >> new  as.complex()  |-->  (Re = NA, Im = 0)
 >> behavior.
 >>
 >> And that is still a valid open question. ... contrary to what I
 >> wrote yesterday; sorry for that "answering a different
 >> question".
 >>
 >> Martin
 >>
 >>
 >> > On Mon, Nov 6, 2023 at 3:08 AM Martin 
Maechler
 >> > wrote:
 >>
 >> >> >>>>> Michael Chirico
 >> >> >>>>> on Sun, 5 Nov 2023 09:41:42 -0800 writes:
 >> >>
 >> >> > This is another follow-up to the thread from September
 >> >> > "Recent changes to as.complex(NA_real_)".
 >> >>
 >> >> > A test in data.table was broken by the changes for NA
 >> >> > coercion to complex; the breakage essentially comes from
 >> >>
 >> >> > c(NA, 0+1i)
 >> >> > # vs
 >> >> > c(as.complex(NA), 0+1i)
 >> >>
 >> >> > The former is the output we tested against; the latter is
 >> >> essentially (via
 >> >> > coerceVector() in C) what's generated by our data.table::shift()
 >> >>
 >> >> > However, these are now (r85472) different:
 >> >>
 >> >> > Im(c(NA, 0+1i))
 >> >> &

Re: [Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?

2023-11-08 Thread Mikael Jagan

So, to summarize, the open questions are:

(1) Should as.complex(NA_character_) give complex(r=NA_real_, i=0)
instead of NA_complex_?

(2) Should the first argument in c(NA, x) and c(NA_integer_, x),
where typeof(x) == "complex", be promoted to complex(r=NA_real_, i=0)
instead of NA_complex_?

My opinions:

(1) No.  The imaginary part of the result of parsing the strings "i",
"+i", and "-i" can be nonzero.
Consider, e.g., Im(eval(str2lang("0+1i"))) and Im(as.complex("0+1i")).
If NA_character_ means "a string with unknown content", then we should
not assume that the string is parsed as a real number.

(2) Yes.  I'd very much like to preserve the identity of c(Im(NA), Im(x))
and Im(c(NA, x)) for atomic (excluding raw, character) vectors 'x'.

And while typing this response I noticed the following in current R-devel and
current R-patched:

> 0+1i
[1] 0+1i
> 1i
[1] 0+1i
> as.complex("0+1i")
[1] 0+1i
> as.complex("1i")
[1] NA
Warning message:
NAs introduced by coercion

That warning seems wrong to me ...

Mikael

On 2023-11-07 6:00 am, r-devel-requ...@r-project.org wrote:

Michael Chirico
 on Mon, 6 Nov 2023 23:18:40 -0800 writes:

 > Thanks Martin. My hang-up was not on what the outcome of as.complex(NA)
 > should be, but rather, how I should read code like c(x, y) generally. 
Till
 > now, I have thought of it like 'c(x, y)' is c(as(x, typeof(y)), y)` when
 > "type(y) > type(x)". Basically in my mind, "coercion" in R <->
 > as.(.) (or coerceVector() in C).

 > So I tracked down the source (which admittedly has been this way for much
 > longer than the present discussion) to see what exactly c() is doing in
 > this case:

 
>https://github.com/r-devel/r-svn/blob/71e7480b07767f3b7d5c45a4247959aa4d83d910/src/main/bind.c#L418-L425

 > And indeed! It's not "coercion" in the sense I just described... there's 
a
 > branch for the 'x == NA_LOGICAL' case to_convert_  to NA_complex_.

Yes; "of course" ... still, I did not answer your main question,
as you did ask +/-  if  c() should not get an adjustment to the
new  as.complex()  |-->  (Re = NA, Im = 0)
behavior.

And that is still a valid open question. ... contrary to what I
wrote yesterday; sorry for that "answering a different
question".

Martin


 > On Mon, Nov 6, 2023 at 3:08 AM Martin 
Maechler
 > wrote:

 >> > Michael Chirico
 >> > on Sun, 5 Nov 2023 09:41:42 -0800 writes:
 >>
 >> > This is another follow-up to the thread from September
 >> > "Recent changes to as.complex(NA_real_)".
 >>
 >> > A test in data.table was broken by the changes for NA
 >> > coercion to complex; the breakage essentially comes from
 >>
 >> > c(NA, 0+1i)
 >> > # vs
 >> > c(as.complex(NA), 0+1i)
 >>
 >> > The former is the output we tested against; the latter is
 >> essentially (via
 >> > coerceVector() in C) what's generated by our data.table::shift()
 >>
 >> > However, these are now (r85472) different:
 >>
 >> > Im(c(NA, 0+1i))
 >> > # [1] NA  1
 >> > Im(c(as.complex(NA), 0+1i))
 >> > # [1] 0 1
 >>
 >>
 >> > The former matches the behavior of directly using NA_complex_:
 >>
 >> > Im(c(NA_complex_, 0+1i))
 >> > # [1] NA  1
 >>
 >> > On R4.3.2, they both match the NA_complex_ behavior:
 >> > Im(c(NA, 0+1i))
 >> > # [1] NA  1
 >> > Im(c(as.complex(NA), 0+1i))
 >> > # [1] NA 1
 >>
 >> > Is this intended behavior, does something need to be updated for c()
 >> as
 >> > well?
 >>
 >> > Certainly it's messing with my understanding of how c() behaves,
 >> e.g. in ?c
 >>
 >> >> All arguments are coerced to a common type which is the type of the
 >> > returned value
 >>
 >> I think you have confused yourself, and everything behaves as expected:
 >>
 >> As we now have (in R-devel, since {r85233 | maechler | 2023-09-29 })
 >>
 >> • ‘as.complex(x)’ now returns ‘complex(real=x, imaginary=0)’
 >> for_all_  numerical and logical ‘x’, notably also for ‘NA’
 >> or ‘NA_integer_’.
 >>
 >> ==> as.complex(NA) is indeed  complex(real = NA, imaginary = 0)
 >>
 >> And now, in your
 >>
 >> c(as.complex(NA), 0+1i)
 >>
 >> you are calling c() on two complex numbers, i.e., there is*no*  coercion
 >> (and c(.) is rather "trivial"),  and the same is true for
 >>
 >> c(NA_complex_, 0+1i)
 >>
 >>
 >> However, in 85233, I had only modified & added examples to  ?as.complex,
 >> and now have added more (corresponding to the above NEWS entry);
 -> svn rev 85475
 >>
 >> .
 >>
 >> The underlying "dilemma" that nobody can help us with is that
 >> "almost infinitely" many different complex numbers z fulfill
 >> is.na(z) |--> TRUE
 

Re: [R-pkg-devel] Matrix and Mac OS

2023-11-02 Thread Mikael Jagan



A hack that seems to work is (whitespace added for readability):

\newcommand{\Seqn}{
  \ifelse{latex}{
\Sexpr[results=rd]{if (getRversion() < "4.2.2") "eqn{#1}" else 
"eqn{#2}"}

  }{
\ifelse{html}{
  \Sexpr[results=rd]{if (getRversion() < "4.2.0") "eqn{#1}" 
else "eqn{#2}"}

}{
  \Sexpr[results=rd]{"eqn{#2}"}
}
  }
}

as amsmath support for PDF output and KaTeX support for HTML output
were introduced in R 4.2.2 and 4.2.0, respectively.

Sadly I really do seem to need 8 escapes:

\Seqn{text{min}(m,n) times n}{min(m,n)-by-n}

Maybe one of the Rd experts here can suggest an improvement ...

Mikael

On 2023-11-01 5:06 am, Martin Maechler wrote:

Uwe Ligges
 on Wed, 1 Nov 2023 06:26:23 +0100 writes:


 > On 01.11.2023 03:51, Mikael Jagan wrote:
 >> Thanks.  It seems that we were mistaken in our feeling (IIRC) that it 
would
 >> be "OK" to implicitly require '--no-manual' on versions of R from 3.5.0 
to
 >> 4.2.1, not changing our Depends.
 >>
 >> We will fix this in Matrix 1.6-2, probably by conditionalizing or 
otherwise
 >> replacing the amsmath commands and probably _not_ by changing to depend 
on
 >> R >= 4.2.2.  Martin may have more to say in "the morning".

I agree (*not* to raise Matrix pkg's R version dependency).

 > Note that dependin on R >= 4.2.2 does not work. We need dependencies of
 > the form R >= x.y.0. This is also part of the checks.

Yes, indeed.
And as we learned, R >= 4.2.0 would not help for r-oldrel-macos

I (am unhappy but) agree to take the responsibility for our
decision to go ahead and use much nicer LaTeX formula for
matrices etc, in our help pages {thinking that indeed people who'd
install Matrix on an old R version would always be able to read
Matrix manual pages via web search (as it seems to me 95% of
people do nowadays) ... or then have someone in their
organization to figure out how to use a newer amsmath (latex) package if
  they really really want the Matrix pdf manual offline}.

Martin

 > Reason is that we have only one binary repository for one R-x.y.?
 > series. On WIndows, where we check with R-4.2.3, a binary would be
 > created and hence R-4.2.[0-1] would not see any valid Matrix binaries.

 > So please either make this work on R >= 4.2.0 or require R >= 4.3.0. If
 > the latter, ideally with an interim version that works for R >= 4.2.0,
 > so that we valid binaries with correct dependency declarations again.

 > Best,
 > Uwe

 >> In the mean time (i.e., while we are stuck with Matrix 1.6-1.1), it may
 >> help
 >> to update to R 4.2.3 on r-oldrel-macos-* and/or to have EdSurvey revert 
its
 >> strict version requirement, unless there are clear examples justifying 
one.
 >>
 >> Mikael
 >>
 >>
 >> On 2023-10-31 8:17 pm, Simon Urbanek wrote:
 >>> Mikael,
 >>>
 >>> in that case I think your requirements are wrong - Matrix says R >=
 >>> 3.5.0 which is apparently incorrect - from what you say it should be
 >>> 4.2.2?. I can certainly update to 4.2.3 if necessary.
 >>>
 >>> Cheers,
 >>> Simon
 >>>
 >>>
 >>>
 >>>> On 1/11/2023, at 9:19 AM, Mikael Jagan  wrote:
 >>>>
 >>>> Thanks.  We did see those ERRORs, stemming from use (since Matrix 
1.6-0)
 >>>> of amsmath commands in Rd files.  These have been supported since R
 >>>> 4.2.2,
 >>>> but r-oldrel-macos-* (unlike r-oldrel-windows-*) continues to run R
 >>>> 4.2.0.
 >>>> My expectation was that those machines would begin running R >= 4.2.2
 >>>> well
 >>>> before the R 4.4.0 release, but apparently that was wrong.
 >>>>
 >>>> I am hesitant to complicate our Rd files with conditions on R versions
 >>>> only to support PDF output for R < 4.2.2, but maybe we can consider it
 >>>> for the Matrix 1.6-2 release if it is really a barrier for others ...
 >>>>
 >>>> Mikael
 >>>>
 >>>> On 2023-10-31 3:33 pm, Simon Urbanek wrote:
 >>>>> Mikael,
 >>>>> current Matrix fails checks on R-oldrel so that's why only the last
 >>>>> working version is installed:
 >>>>> https://cran.r-project.org/web/checks/check_results_Matrix.html
 >>>>&g

Re: [R-pkg-devel] Matrix and Mac OS

2023-11-02 Thread Mikael Jagan





On 2023-11-01 12:59 pm, Mikael Jagan wrote:

A hack that seems to work is (whitespace added for readability):

  \newcommand{\Seqn}{
\ifelse{latex}{
  \Sexpr[results=rd]{if (getRversion() < "4.2.2") "eqn{#1}" else
"eqn{#2}"}
}{
  \ifelse{html}{
\Sexpr[results=rd]{if (getRversion() < "4.2.0") "eqn{#1}"
else "eqn{#2}"}
  }{
\Sexpr[results=rd]{"eqn{#2}"}
  }
}
  }


Er, the above is wrong, because '<' should be '>=' and because '#2' (which
is conceptually verbatim text) should use \verb{} for PDF and HTML output,
not \eqn{}.  For Matrix 1.6-2 I have created man/macros/local.Rd and added:

\newcommand{\Seqn}{\ifelse{latex}{\Sexpr[results=rd]{if (getRversion() >= 
"4.2.2") "eqn{#1}" else 
"verb{#2}"}}{\ifelse{html}{\Sexpr[results=rd]{if (getRversion() >= 
"4.2.0") "eqn{#1}" else 
"verb{#2}"}}{\Sexpr[results=rd]{"eqn{#2}"


\newcommand{\Sdeqn}{\ifelse{latex}{\Sexpr[results=rd]{if (getRversion() >= 
"4.2.2") "deqn{#1}" else 
"preformatted{#2}"}}{\ifelse{html}{\Sexpr[results=rd]{if (getRversion() 
>= "4.2.0") "deqn{#1}" else 
"preformatted{#2}"}}{\Sexpr[results=rd]{"deqn{#2}"


Now Matrix 1.6-2 passes its Rd checks under my checkout of R-3-5-branch.
Some examples and tests fail for unrelated reasons.  I'll fix those, too ...

Mikael



as amsmath support for PDF output and KaTeX support for HTML output
were introduced in R 4.2.2 and 4.2.0, respectively.

Sadly I really do seem to need 8 escapes:

  \Seqn{text{min}(m,n) times n}{min(m,n)-by-n}

Maybe one of the Rd experts here can suggest an improvement ...

Mikael

On 2023-11-01 5:06 am, Martin Maechler wrote:

Uwe Ligges
  on Wed, 1 Nov 2023 06:26:23 +0100 writes:


  > On 01.11.2023 03:51, Mikael Jagan wrote:
  >> Thanks.  It seems that we were mistaken in our feeling (IIRC) that it 
would
  >> be "OK" to implicitly require '--no-manual' on versions of R from 
3.5.0 to
  >> 4.2.1, not changing our Depends.
  >>
  >> We will fix this in Matrix 1.6-2, probably by conditionalizing or 
otherwise
  >> replacing the amsmath commands and probably _not_ by changing to 
depend on
  >> R >= 4.2.2.  Martin may have more to say in "the morning".

I agree (*not* to raise Matrix pkg's R version dependency).

  > Note that dependin on R >= 4.2.2 does not work. We need dependencies of
  > the form R >= x.y.0. This is also part of the checks.

Yes, indeed.
And as we learned, R >= 4.2.0 would not help for r-oldrel-macos

I (am unhappy but) agree to take the responsibility for our
decision to go ahead and use much nicer LaTeX formula for
matrices etc, in our help pages {thinking that indeed people who'd
install Matrix on an old R version would always be able to read
Matrix manual pages via web search (as it seems to me 95% of
people do nowadays) ... or then have someone in their
organization to figure out how to use a newer amsmath (latex) package if
   they really really want the Matrix pdf manual offline}.

Martin

  > Reason is that we have only one binary repository for one R-x.y.?
  > series. On WIndows, where we check with R-4.2.3, a binary would be
  > created and hence R-4.2.[0-1] would not see any valid Matrix binaries.

  > So please either make this work on R >= 4.2.0 or require R >= 4.3.0. If
  > the latter, ideally with an interim version that works for R >= 4.2.0,
  > so that we valid binaries with correct dependency declarations again.

  > Best,
  > Uwe

  >> In the mean time (i.e., while we are stuck with Matrix 1.6-1.1), it may
  >> help
  >> to update to R 4.2.3 on r-oldrel-macos-* and/or to have EdSurvey 
revert its
  >> strict version requirement, unless there are clear examples justifying 
one.
  >>
  >> Mikael
  >>
  >>
  >> On 2023-10-31 8:17 pm, Simon Urbanek wrote:
  >>> Mikael,
  >>>
  >>> in that case I think your requirements are wrong - Matrix says R >=
  >>> 3.5.0 which is apparently incorrect - from what you say it should be
  >>> 4.2.2?. I can certainly update to 4.2.3 if necessary.
  >>>
  >>> Cheers,
  >>> Simon
  >>>
  >>>
  >>>
  >>>> On 1/11/2023, at 9:19 AM, Mikael Jagan  wrote:
  >>>>
  >>>> Thanks.  We d

Re: [R-pkg-devel] Matrix and Mac OS

2023-10-31 Thread Mikael Jagan

Thanks.  It seems that we were mistaken in our feeling (IIRC) that it would
be "OK" to implicitly require '--no-manual' on versions of R from 3.5.0 to
4.2.1, not changing our Depends.

We will fix this in Matrix 1.6-2, probably by conditionalizing or otherwise
replacing the amsmath commands and probably _not_ by changing to depend on
R >= 4.2.2.  Martin may have more to say in "the morning".

In the mean time (i.e., while we are stuck with Matrix 1.6-1.1), it may help
to update to R 4.2.3 on r-oldrel-macos-* and/or to have EdSurvey revert its
strict version requirement, unless there are clear examples justifying one.

Mikael


On 2023-10-31 8:17 pm, Simon Urbanek wrote:

Mikael,

in that case I think your requirements are wrong - Matrix says R >= 3.5.0 which 
is apparently incorrect - from what you say it should be 4.2.2?. I can certainly 
update to 4.2.3 if necessary.

Cheers,
Simon




On 1/11/2023, at 9:19 AM, Mikael Jagan  wrote:

Thanks.  We did see those ERRORs, stemming from use (since Matrix 1.6-0)
of amsmath commands in Rd files.  These have been supported since R 4.2.2,
but r-oldrel-macos-* (unlike r-oldrel-windows-*) continues to run R 4.2.0.
My expectation was that those machines would begin running R >= 4.2.2 well
before the R 4.4.0 release, but apparently that was wrong.

I am hesitant to complicate our Rd files with conditions on R versions
only to support PDF output for R < 4.2.2, but maybe we can consider it
for the Matrix 1.6-2 release if it is really a barrier for others ...

Mikael

On 2023-10-31 3:33 pm, Simon Urbanek wrote:

Mikael,
current Matrix fails checks on R-oldrel so that's why only the last working 
version is installed:
https://cran.r-project.org/web/checks/check_results_Matrix.html
Cheers,
Simon

On 1/11/2023, at 4:05 AM, Mikael Jagan  wrote:

I am guessing that they mean EdSurvey:

https://cran.r-project.org/web/checks/check_results_EdSurvey.html

Probably Matrix 1.6-1.1 is not installed on r-oldrel-macos-arm64,
even though it can be, because it was not released until R 4.3-z.

AFAIK, methods for 'qr' have not been touched since Matrix 1.6-0, and
even those changes should have been backwards compatible, modulo handling
of dimnames (class sparseQR gained a Dimnames slot in 1.6-0).

So I don't see a clear reason for requiring 1.6-1.1.  Requiring 1.6-0
might make sense, if somehow EdSurvey depends on how class sparseQR
preserves dimnames.  But IIRC our rev. dep. checks at that time did not
reveal problems with EdSurvey.

Mikael

On 2023-10-31 7:00 am, r-package-devel-requ...@r-project.org wrote:

Paul,
can you give us a bit more detail? Which package, which build and where you got 
the errors? Older builds may not have the latest Matrix.
Cheers,
Simon

On 31/10/2023, at 11:26 AM, Bailey, Paul via 
R-package-devel  wrote:

Hi,

I'm the maintainer for a few packages, one of which is currently failing CRAN checks on 
Mac OS because Matrix is not available in my required version (the latest). I had to fix 
a few things due to changes in the latest Matrix package because of how qr works and I 
thought, given the apparent API change, I should then require the latest version. My 
error is, "Package required and available but unsuitable version: 'Matrix'"

When I look at the NEWS in Matrix there is no mention of Mac OS issues, what 
the latest stable version of Matrix is, nor when a fix is expected. What 
version do MacOS version test Matrix with by default? Where is this documented? 
I assumes it always tested with the latest version on CRAN, so I'm a bit 
surprised. Or will this be resolved soon and I shouldn't bother CRAN 
maintainers with a new version of my package?

Best,
Paul

[[alternative HTML version deleted]]








__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Matrix and Mac OS

2023-10-31 Thread Mikael Jagan

Thanks.  We did see those ERRORs, stemming from use (since Matrix 1.6-0)
of amsmath commands in Rd files.  These have been supported since R 4.2.2,
but r-oldrel-macos-* (unlike r-oldrel-windows-*) continues to run R 4.2.0.
My expectation was that those machines would begin running R >= 4.2.2 well
before the R 4.4.0 release, but apparently that was wrong.

I am hesitant to complicate our Rd files with conditions on R versions
only to support PDF output for R < 4.2.2, but maybe we can consider it
for the Matrix 1.6-2 release if it is really a barrier for others ...

Mikael

On 2023-10-31 3:33 pm, Simon Urbanek wrote:

Mikael,

current Matrix fails checks on R-oldrel so that's why only the last working 
version is installed:
https://cran.r-project.org/web/checks/check_results_Matrix.html

Cheers,
Simon




On 1/11/2023, at 4:05 AM, Mikael Jagan  wrote:

I am guessing that they mean EdSurvey:

https://cran.r-project.org/web/checks/check_results_EdSurvey.html

Probably Matrix 1.6-1.1 is not installed on r-oldrel-macos-arm64,
even though it can be, because it was not released until R 4.3-z.

AFAIK, methods for 'qr' have not been touched since Matrix 1.6-0, and
even those changes should have been backwards compatible, modulo handling
of dimnames (class sparseQR gained a Dimnames slot in 1.6-0).

So I don't see a clear reason for requiring 1.6-1.1.  Requiring 1.6-0
might make sense, if somehow EdSurvey depends on how class sparseQR
preserves dimnames.  But IIRC our rev. dep. checks at that time did not
reveal problems with EdSurvey.

Mikael

On 2023-10-31 7:00 am, r-package-devel-requ...@r-project.org wrote:

Paul,
can you give us a bit more detail? Which package, which build and where you got 
the errors? Older builds may not have the latest Matrix.
Cheers,
Simon

On 31/10/2023, at 11:26 AM, Bailey, Paul via 
R-package-devel  wrote:

Hi,

I'm the maintainer for a few packages, one of which is currently failing CRAN checks on 
Mac OS because Matrix is not available in my required version (the latest). I had to fix 
a few things due to changes in the latest Matrix package because of how qr works and I 
thought, given the apparent API change, I should then require the latest version. My 
error is, "Package required and available but unsuitable version: 'Matrix'"

When I look at the NEWS in Matrix there is no mention of Mac OS issues, what 
the latest stable version of Matrix is, nor when a fix is expected. What 
version do MacOS version test Matrix with by default? Where is this documented? 
I assumes it always tested with the latest version on CRAN, so I'm a bit 
surprised. Or will this be resolved soon and I shouldn't bother CRAN 
maintainers with a new version of my package?

Best,
Paul

[[alternative HTML version deleted]]






__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Matrix and Mac OS

2023-10-31 Thread Mikael Jagan

Re-sending to the list with correct subject line ...

I should undigest myself ...

Mikael

On 2023-10-31 11:05 am, Mikael Jagan wrote:

I am guessing that they mean EdSurvey:

  https://cran.r-project.org/web/checks/check_results_EdSurvey.html

Probably Matrix 1.6-1.1 is not installed on r-oldrel-macos-arm64,
even though it can be, because it was not released until R 4.3-z.

AFAIK, methods for 'qr' have not been touched since Matrix 1.6-0, and
even those changes should have been backwards compatible, modulo handling
of dimnames (class sparseQR gained a Dimnames slot in 1.6-0).

So I don't see a clear reason for requiring 1.6-1.1.  Requiring 1.6-0
might make sense, if somehow EdSurvey depends on how class sparseQR
preserves dimnames.  But IIRC our rev. dep. checks at that time did not
reveal problems with EdSurvey.

Mikael

On 2023-10-31 7:00 am, r-package-devel-requ...@r-project.org wrote:

Paul,

can you give us a bit more detail? Which package, which build and where you got 
the errors? Older builds may not have the latest Matrix.

Cheers,
Simon



On 31/10/2023, at 11:26 AM, Bailey, Paul via 
R-package-devel  wrote:

Hi,

I'm the maintainer for a few packages, one of which is currently failing CRAN checks on 
Mac OS because Matrix is not available in my required version (the latest). I had to fix 
a few things due to changes in the latest Matrix package because of how qr works and I 
thought, given the apparent API change, I should then require the latest version. My 
error is, "Package required and available but unsuitable version: 'Matrix'"

When I look at the NEWS in Matrix there is no mention of Mac OS issues, what 
the latest stable version of Matrix is, nor when a fix is expected. What 
version do MacOS version test Matrix with by default? Where is this documented? 
I assumes it always tested with the latest version on CRAN, so I'm a bit 
surprised. Or will this be resolved soon and I shouldn't bother CRAN 
maintainers with a new version of my package?

Best,
Paul

[[alternative HTML version deleted]]


__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] R-package-devel Digest, Vol 102, Issue 27

2023-10-31 Thread Mikael Jagan

I am guessing that they mean EdSurvey:

https://cran.r-project.org/web/checks/check_results_EdSurvey.html

Probably Matrix 1.6-1.1 is not installed on r-oldrel-macos-arm64,
even though it can be, because it was not released until R 4.3-z.

AFAIK, methods for 'qr' have not been touched since Matrix 1.6-0, and
even those changes should have been backwards compatible, modulo handling
of dimnames (class sparseQR gained a Dimnames slot in 1.6-0).

So I don't see a clear reason for requiring 1.6-1.1.  Requiring 1.6-0
might make sense, if somehow EdSurvey depends on how class sparseQR
preserves dimnames.  But IIRC our rev. dep. checks at that time did not
reveal problems with EdSurvey.

Mikael

On 2023-10-31 7:00 am, r-package-devel-requ...@r-project.org wrote:

Paul,

can you give us a bit more detail? Which package, which build and where you got 
the errors? Older builds may not have the latest Matrix.

Cheers,
Simon



On 31/10/2023, at 11:26 AM, Bailey, Paul via 
R-package-devel  wrote:

Hi,

I'm the maintainer for a few packages, one of which is currently failing CRAN checks on 
Mac OS because Matrix is not available in my required version (the latest). I had to fix 
a few things due to changes in the latest Matrix package because of how qr works and I 
thought, given the apparent API change, I should then require the latest version. My 
error is, "Package required and available but unsuitable version: 'Matrix'"

When I look at the NEWS in Matrix there is no mention of Mac OS issues, what 
the latest stable version of Matrix is, nor when a fix is expected. What 
version do MacOS version test Matrix with by default? Where is this documented? 
I assumes it always tested with the latest version on CRAN, so I'm a bit 
surprised. Or will this be resolved soon and I shouldn't bother CRAN 
maintainers with a new version of my package?

Best,
Paul

[[alternative HTML version deleted]]


__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Question regarding listing base and recommended packages programmatically and efficiently

2023-10-12 Thread Mikael Jagan

Maybe something like this:

> isRecommendedPkg <- utils:::isBasePkg
> body(isRecommendedPkg)[[c(3L, 3L)]] <- "recommended"
> installed <- unique(list.files(.libPaths()))
> installed[vapply(installed, isRecommendedPkg, NA)]
 [1] "KernSmooth" "MASS"   "Matrix" "boot"   "class"
 [6] "cluster""codetools"  "foreign""lattice""mgcv"
[11] "nlme"   "nnet"   "rpart"  "spatial""survival"

where in your package you would define isRecommendedPkg "manually".

Another (but quite undocumented and so maybe not "recommended" :-))
possibility is this:

> mk <- file.path(R.home("share"), "make", "vars.mk")
> pp <- sub("^.*= +", "", grep("^R_PKGS_RECOMMENDED", readLines(mk), value 
= TRUE))

> sort(strsplit(pp, " ")[[1L]])
 [1] "KernSmooth" "MASS"   "Matrix" "boot"   "class"
 [6] "cluster""codetools"  "foreign""lattice""mgcv"
[11] "nlme"   "nnet"   "rpart"  "spatial""survival"

I grepped around and did not find variables in any base namespace containing
the names of these packages.  It wouldn't be too hard to define such variables
when R is configured/built, but maybe there are "reasons" to not do that ... ?

Mikael

> It would be much faster (but slightly less reliable) to use
> list.files(.libPaths()) to get the names of all installed packages, and
> then filter them to the known list of base and recommended packages,
> which changes very rarely.
>
> Duncan Murdoch
>
> On 12/10/2023 8:34 a.m., Tony Wilkes wrote:
> > Dear all,
> >
> > In my R package that I'm developing, I use `installed.packages(priority = 
"base")` to programmatically get all core/base R packages (i.e. base, stats, 
etc.). And similarly, I use installed.packages(priority = "recommended")​` to 
programmatically get the recommended R packages (i.e. mgcv, lattice, etc.).

> >
> > However, CRAN has requested to not use `installed.packages()`, as it is 
slow. I fully get and agree with that assesment. I used installed.packages()​` 
anyway because I could not find a better, fool-proof alternative.

> >
> > Nonetheless, I was asked to change this code for optimalisation. So I would 
like to ask: how do I programmatically get all base/core R packages safely and 
efficiently, but without using `installed.packages()`? And the same question for 
recommended R packages. I have of course Googled it, and looked at R's 
documentation (though R's documentation is large, so it's easy to miss 
something); no solution found. So if any of you has a smart idea: I'm all ears.

> >
> > Thank you in advance.
> >
> > Kind regards,
> >
> > Tony.

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Note: no function found corresponding to methods exports for show

2023-10-09 Thread Mikael Jagan




On 2023-10-08 5:43 pm, Mikael Jagan wrote:

Hi,

I recently submitted my first R package to CRAN, and I encountered a NOTE
during the checking process. The NOTE looks like this:

=
Flavor: r-devel-linux-x86_64-debian-gcc, r-devel-windows-x86_64
Check: whether the namespace can be loaded with stated dependencies,
Result: NOTE
Warning: no function found corresponding to methods exports from 'hmsr'
for: 'show'

A namespace must be able to be loaded with just the base namespace
loaded: otherwise if the namespace gets loaded by a saved object, the
session will be unable to start.

Probably some imports need to be declared in the NAMESPACE file.


Sounds like your NAMESPACE is missing importFrom(methods, show) ... ?
I'm not sure why you could not reproduce the problem locally, given that
check uses _R_CHECK_CODE_USAGE_WITH_ONLY_BASE_ATTACHED_=true by default.


Reading tools:::.check_packages I see that this environment variable is
not relevant to this particular test.  Still, do import generic functions
for which you define methods, from all packages != "base".

Mikael


But it is hard to say anything without a link to the package sources ...

Mikael


=

I'm seeking help to understand and address this issue. show is defined like
this:

#' Show method for class "hms".#'#' @param object - hms s4 object#'#'
@return It returns the names of the slots and the classes associated
with the#' slots in the "hms" class. It prints call details.#'#'
@export#'#' @examples
#' f <- function(x) x
#' result <- hms(fitness = f, lower = -5, upper = 5)
#' show(result)
setMethod("show", "hms", function(object) {
cat("An object of class \"hms\"\n")
cat("\nCall:\n", deparse(object@call), "\n\n", sep = "")
cat("Available slots:\n")
print(methods::slotNames(object))})

And in the NAMESPACE there is a line that looks like this:

exportMethods(show)

I was investigating if the show is defined correctly and the GA package has
a very similar method:

setMethod("show", "ga",function(object)
   { cat("An object of class \"ga\"\n")
 cat("\nCall:\n", deparse(object@call), "\n\n",sep="")
 cat("Available slots:\n")
 print(slotNames(object))})

I could not reproduce this NOTE on my personal machine with Windows.
On Mac OS I have never experienced this NOTE.


Best regards

Wojciech Achtelik


__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Note: no function found corresponding to methods exports for show

2023-10-08 Thread Mikael Jagan

Hi,

I recently submitted my first R package to CRAN, and I encountered a NOTE
during the checking process. The NOTE looks like this:

=
Flavor: r-devel-linux-x86_64-debian-gcc, r-devel-windows-x86_64
Check: whether the namespace can be loaded with stated dependencies,
Result: NOTE
   Warning: no function found corresponding to methods exports from 'hmsr'
for: 'show'

   A namespace must be able to be loaded with just the base namespace
   loaded: otherwise if the namespace gets loaded by a saved object, the
   session will be unable to start.

   Probably some imports need to be declared in the NAMESPACE file.


Sounds like your NAMESPACE is missing importFrom(methods, show) ... ?
I'm not sure why you could not reproduce the problem locally, given that
check uses _R_CHECK_CODE_USAGE_WITH_ONLY_BASE_ATTACHED_=true by default.
But it is hard to say anything without a link to the package sources ...

Mikael


=

I'm seeking help to understand and address this issue. show is defined like
this:

#' Show method for class "hms".#'#' @param object - hms s4 object#'#'
@return It returns the names of the slots and the classes associated
with the#' slots in the "hms" class. It prints call details.#'#'
@export#'#' @examples
#' f <- function(x) x
#' result <- hms(fitness = f, lower = -5, upper = 5)
#' show(result)
setMethod("show", "hms", function(object) {
   cat("An object of class \"hms\"\n")
   cat("\nCall:\n", deparse(object@call), "\n\n", sep = "")
   cat("Available slots:\n")
   print(methods::slotNames(object))})

And in the NAMESPACE there is a line that looks like this:

exportMethods(show)

I was investigating if the show is defined correctly and the GA package has
a very similar method:

setMethod("show", "ga",function(object)
  { cat("An object of class \"ga\"\n")
cat("\nCall:\n", deparse(object@call), "\n\n",sep="")
cat("Available slots:\n")
print(slotNames(object))})

I could not reproduce this NOTE on my personal machine with Windows.
On Mac OS I have never experienced this NOTE.


Best regards

Wojciech Achtelik


__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [Rd] as(, "dgTMatrix")' is deprecated.

2023-10-04 Thread Mikael Jagan
> There is a call to mosek and I assumed that this wasn’t going to be helpful 
for most R-devel recipients.  I tried Duncan’s very reasonable suggestion about 
options() but it didn’t produce the desired error, so perhaps this isn’t really 
a warning  but something else???

>

The details are described in news(package="Matrix") under "Changes in version
1.5-0" and implemented in Matrix:::Matrix.DeprecatedCoerce.  That version was
released in Sep 2022.

At the time, it was too disruptive to signal a proper deprecation warning
with every as(., "d(g.|.C)Matrix") call, for every reverse dependency of
Matrix, so we decided that in those most common cases we would use message()
instead of warning().   A corollary was that options(warn=n) would not have
the usual effect, so we advertised an alternative to affected maintainers:

in R:

options(Matrix.warnDeprecatedCoerce=n)

on the command line:

R_MATRIX_WARN_DEPRECATED_COERCE=n R CMD check *.tar.gz

But maybe it is time to begin signaling warnings unconditionally ...

Mikael

> For those who might have rmosek installed,  I’m doing:
>
> library(REBayes)
> demo(GLmix1)
>
> Thanks,
> Roger
>
>
> > On Oct 3, 2023, at 6:17 PM, Martin Maechler stat.math.ethz.ch> wrote:

> >
> >> Duncan Murdoch
> >>on Tue, 3 Oct 2023 12:59:10 -0400 writes:
> >
> >> On 03/10/2023 12:50 p.m., Koenker, Roger W wrote:
> >>> I’ve been getting this warning for a while now (about
> >>> five years if memory serves) and I’m finally tired of it,
> >>> but also too tired to track it down in Matrix.  As far as
> >>> I can grep I have no reference to either deprecated
> >>> object, only the apparently innocuous Matrix::Matrix(A,
> >>> sparse = TRUE).  Can someone advise, Martin perhaps?  I
> >>> thought it might come from Rmosek, but mosek folks don’t
> >>> think so.
> >>> 
https://urldefense.com/v3/__https://groups.google.com/g/mosek/c/yEwXmMfHBbg/m/l_mkeM4vAAAJ__;!!DZ3fjg!71re8ipw9fFStkMab0wGuPNSzSaAhPI5vwxd1BCQ7a55mYiRpAq2prn9-wREqKL_G2uBYboXISQfxZYCZ9AFxCnwxdzqTw$ 


> >
> >> A quick scan of that discussion didn't turn up anything
> >> relevant, e.g. a script to produce the warning.  Could you
> >> be more specific, or just post the script here?
> >
> >> In general, a good way to locate the source of a warning
> >> is to set options(warn=2) to turn it into an error, and
> >> then trigger it.  The traceback from the error will
> >> include a bunch of junk from the code that catches the
> >> warning, but it will also include the context where it was
> >> triggered.
> >
> >> Duncan Murdoch
> >
> > Indeed.
> >
> > But Roger is right that it in the end, (almost surely) it is
> > from our {Matrix} package.
> >
> > Indeed for several years now, we have tried to make the setup
> > leaner (and hence faster) by not explicitly define coercion
> > from  to   because  the size of
> >  is here about 200, and we don't want to have to provide
> > 200^2 = 40'000  coercion methods.
> >
> > Rather, Matrix package users should use to high level abstract Matrix
> > classes such as "sparseMatrix" or "CsparseMatrix" or
> > "TsparseMatrix" or "dMatrix", "symmetricMatrix".
> >
> > In the case of  as(, "dgTMatrix") , if you
> > replace "dgTMatrix" by "TsparseMatrix"
> > the result will be the same but also work in the future when the
> > deprecation may have been turned into a defunctation ...
> >
> > Martin

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Recent changes to as.complex(NA_real_)

2023-09-23 Thread Mikael Jagan




On 2023-09-23 9:43 am, Martin Maechler wrote:

Hervé Pagès
 on Fri, 22 Sep 2023 16:55:05 -0700 writes:


 > The problem is that you have things that are
 > **semantically** different but look exactly the same:

 > They look the same:

 >> x
 > [1] NA
 >> y
 > [1] NA
 >> z
 > [1] NA

 >> is.na(x)
 > [1] TRUE
 >> is.na(y)
 > [1] TRUE
 >> is.na(z)
 > [1] TRUE

 >> str(x)
 >   cplx NA
 >> str(y)
 >   num NA
 >> str(z)
 >   cplx NA

 > but they are semantically different e.g.

 >> Re(x)
 > [1] NA
 >> Re(y)
 > [1] -0.5  # surprise!

 >> Im(x)  # surprise!
 > [1] 2
 >> Im(z)
 > [1] NA

 > so any expression involving Re() or Im() will produce
 > different results on input that look the same on the
 > surface.

 > You can address this either by normalizing the internal
 > representation of complex NA to always be complex(r=NaN,
 > i=NA_real_), like for NA_complex_, or by allowing the
 > infinite variations that are currently allowed and at the
 > same time making sure that both Re() and Im()  always
 > return NA_real_ on a complex NA.

 > My point is that the behavior of complex NA should be
 > predictable. Right now it's not. Once it's predictable
 > (with Re() and Im() both returning NA_real_ regardless of
 > internal representation), then it no longer matters what
 > kind of complex NA is returned by as.complex(NA_real_),
 > because they are no onger distinguishable.

 > H.

 > On 9/22/23 13:43, Duncan Murdoch wrote:
 >> Since the result of is.na(x) is the same on each of
 >> those, I don't see a problem.  As long as that is
 >> consistent, I don't see a problem. You shouldn't be using
 >> any other test for NA-ness.  You should never be
 >> expecting identical() to treat different types as the
 >> same (e.g.  identical(NA, NA_real_) is FALSE, as it
 >> should be).  If you are using a different test, that's
 >> user error.
 >>
 >> Duncan Murdoch
 >>
 >> On 22/09/2023 2:41 p.m., Hervé Pagès wrote:
 >>> We could also question the value of having an infinite
 >>> number of NA representations in the complex space. For
 >>> example all these complex values are displayed the same
 >>> way (as NA), are considered NAs by is.na(), but are not
 >>> identical or semantically equivalent (from an Re() or
 >>> Im() point of view):
 >>>
 >>>       NA_real_ + 0i
 >>>
 >>>       complex(r=NA_real_, i=Inf)
 >>>
 >>>       complex(r=2, i=NA_real_)
 >>>
 >>>       complex(r=NaN, i=NA_real_)
 >>>
 >>> In other words, using a single representation for
 >>> complex NA (i.e.  complex(r=NA_real_, i=NA_real_)) would
 >>> avoid a lot of unnecessary complications and surprises.
 >>>
 >>> Once you do that, whether as.complex(NA_real_) should
 >>> return complex(r=NA_real_, i=0) or complex(r=NA_real_,
 >>> i=NA_real_) becomes a moot point.
 >>>
 >>> Best,
 >>>
 >>> H.

Thank you, Hervé.
Your proposition is yet another one,
to declare that all complex NA's should be treated as identical
(almost/fully?) everywhere.

This would be a possibility, but I think a drastic one.

I think there are too many cases, where I want to keep the
information of the real part independent of the values of the
imaginary part (e.g. think of the Riemann hypothesis), and
typically vice versa.

With your proposal, for a (potentially large) vector of complex numbers,
after
   Re(z)  <-  1/2

I could no longer rely on   Re(z) == 1/2,
because it would be wrong for those z where (the imaginary part/ the number)
was NA/NaN.
Also, in a similar case, a

   Im(z) <- NA

would have to "destroy" all real parts  Re(z);
not really typically in memory, but effectively for the user,  Re(z)
would be all NA/NaN.

And I think there are quite a few other situations
where looking at Re() and Im() separately makes a lot of sense.


Indeed, and there is no way to "tell" BLAS and LAPACK to treat both the real and
imaginary parts as NA_REAL when either is NA_REAL.  Hence the only reliable way
to implement such a proposal would be to post-process the result of any
computation returning a complex type, testing for NA_REAL and setting both parts
to NA_REAL in that case.  My expectation is that such testing would drastically
slow down basic 

Re: [Rd] Recent changes to as.complex(NA_real_)

2023-09-22 Thread Mikael Jagan




On 2023-09-22 6:38 am, Martin Maechler wrote:

Mikael Jagan
 on Thu, 21 Sep 2023 00:47:39 -0400 writes:


 > Revisiting this thread from April:

 >  https://stat.ethz.ch/pipermail/r-devel/2023-April/082545.html

 > where the decision (not yet backported) was made for
 > as.complex(NA_real_) to give NA_complex_ instead of
 > complex(r=NA_real_, i=0), to be consistent with
 > help("as.complex") and as.complex(NA) and as.complex(NA_integer_).

 > Was any consideration given to the alternative?
 > That is, to changing as.complex(NA) and as.complex(NA_integer_) to
 > give complex(r=NA_real_, i=0), consistent with
 > as.complex(NA_real_), then amending help("as.complex")
 > accordingly?

Hmm, as, from R-core, mostly I was involved, I admit to say "no",
to my knowledge the (above) alternative wasn't considered.

   > The principle that
   > Im(as.complex()) should be zero
   > is quite fundamental, in my view, hence the "new" behaviour
   > seems to really violate the principle of least surprise ...

of course "least surprise"  is somewhat subjective.  Still,
I clearly agree that the above would be one desirable property.

I think that any solution will lead to *some* surprise for some
cases, I think primarily because there are *many* different
values z  for which  is.na(z)  is true,  and in any case
NA_complex_  is only of the many.

I also agree with Mikael that we should reconsider the issue
that was raised by Davis Vaughan here ("on R-devel") last April.

 > Another (but maybe weaker) argument is that
 > double->complex coercions happen more often than
 > logical->complex and integer->complex ones.  Changing the
 > behaviour of the more frequently performed coercion is
 > more likely to affect code "out there".

 > Yet another argument is that one expects

 >  identical(as.complex(NA_real_), NA_real_ + (0+0i))

 > to be TRUE, i.e., that coercing from double to complex is
 > equivalent to adding a complex zero.  The new behaviour
 > makes the above FALSE, since NA_real_ + (0+0i) gives
 > complex(r=NA_real_, i=0).

No!  --- To my own surprise (!) --- in current R-devel the above is TRUE,
and
   NA_real_ + (0+0i)  , the same as
   NA_real_ + 0i  , really gives  complex(r=NA, i=NA) :



Thank you for the correction - indeed, as.complex(NA_real_) and
NA_real_ + (0+0i) are identical in both R-patched and R-devel,
both giving complex(r=NA_real_, i=0) in R-patched and both giving
NA_complex_ in R-devel.  I was hallucating, it seems ...


Using showC() from ?complex

   showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))

we see (in R-devel) quite consistently


showC(NA_real_ + 0i)

[1] (R = NA, I = NA)

showC(NA   + 0i)  # NA is 'logical'

[1] (R = NA, I = NA)




where as in R 4.3.1 and "R-patched" -- *in*consistently


showC(NA_real_ + 0i)

[1] (R = NA, I = 0)

showC(NA + 0i)

[1] (R = NA, I = NA)




 and honestly, I do not see *where* (and when) we changed
the underlying code (in arithmetic.c !?)  in R-devel to *also*
produce  NA_complex_  in such complex *arithmetic*



R_binary() in arithmetic.c has always coerced REALSXP->CPLXSXP when
encountering one of each.  Surely then the changes in coerce.c are the
cause and this arithmetic behaviour is just a (bad, IMO) side effect?



 > Having said that, one might also (but more naively) expect

 > identical(as.complex(as.double(NA_complex_)), NA_complex_)

 > to be TRUE.

as in current R-devel

 > Under my proposal it continues to be FALSE.

as in "R-release"

 > Well, I'd prefer if it gave FALSE with a warning
 > "imaginary parts discarded in coercion", but it seems that
 > as.double(complex(r=a, i=b)) never warns when either of
 > 'a' and 'b' is NA_real_ or NaN, even where "information"
 > {nonzero 'b'} is clearly lost ...

The question of *warning* here is related indeed, but I think
we should try to look at it only *secondary* to your first
proposal.

 > Whatever decision is made about as.complex(NA_real_),
 > maybe these points should be weighed before it becomes part of
 > R-release ...

 > Mikael

Indeed.

Can we please get other opinions / ideas here?



Thank you, Martin, for "reopening".

Mikael


Thank you in advance for your thoughts!
Martin

---

PS:

  Our *print()*ing  of complex NA's ("NA" here meaning NA or NaN)
  is also unsatisfactory, e.g. in the case where all entries of a
  vector are NA in the sense of is.na(.), but their
  Re() and Im() are not all NA:
  
   showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))

   z <- complex(, c(11, NA, NA)

[Rd] Recent changes to as.complex(NA_real_)

2023-09-20 Thread Mikael Jagan

Revisiting this thread from April:

https://stat.ethz.ch/pipermail/r-devel/2023-April/082545.html

where the decision (not yet backported) was made for as.complex(NA_real_)
to give NA_complex_ instead of complex(r=NA_real_, i=0), to be consistent
with help("as.complex") and as.complex(NA) and as.complex(NA_integer_).

Was any consideration given to the alternative?  That is, to changing
as.complex(NA) and as.complex(NA_integer_) to give complex(r=NA_real_, i=0),
consistent with as.complex(NA_real_), then amending help("as.complex")
accordingly?

The principle that Im(as.complex()) should
be zero is quite fundamental, in my view, hence the "new" behaviour seems
to really violate the principle of least surprise ...

Another (but maybe weaker) argument is that double->complex coercions happen
more often than logical->complex and integer->complex ones.  Changing the
behaviour of the more frequently performed coercion is more likely to affect
code "out there".

Yet another argument is that one expects

identical(as.complex(NA_real_), NA_real_ + (0+0i))

to be TRUE, i.e., that coercing from double to complex is equivalent to
adding a complex zero.  The new behaviour makes the above FALSE, since
NA_real_ + (0+0i) gives complex(r=NA_real_, i=0).

Having said that, one might also (but more naively) expect

identical(as.complex(as.double(NA_complex_)), NA_complex_)

to be TRUE.  Under my proposal it continues to be FALSE.  Well, I'd prefer
if it gave FALSE with a warning "imaginary parts discarded in coercion",
but it seems that as.double(complex(r=a, i=b)) never warns when either of
'a' and 'b' is NA_real_ or NaN, even where "information" {nonzero 'b'} is
clearly lost ...

Whatever decision is made about as.complex(NA_real_), maybe these points
should be weighed before it becomes part of R-release ...

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] R-devel Digest, Vol 246, Issue 6

2023-08-07 Thread Mikael Jagan

Two quite related and recent threads on R-devel:

[1] proposal for WRE: clarify that use of S4 classes implies use of superclasses
https://stat.ethz.ch/pipermail/r-devel/2023-July/082739.html
[2] Should package version requirements assume installation from sources?
https://stat.ethz.ch/pipermail/r-devel/2022-September/081971.html

Notably, if SeuratObject 4.1.3, the current version, had

importClassesFrom(Matrix, dgCMatrix,
  ## and the exported superclasses:
  CsparseMatrix, Matrix, compMatrix, dMatrix,
  dsparseMatrix, generalMatrix, sparseMatrix)

and not just

importClassesFrom(Matrix, dgCMatrix)

then the silent breakage due to missing symbols would not have occurred.
That is because _imported_ class definitions are retrieved at load time,
not at install time.  SeuratObject 4.1.3 retrieves the CsparseMatrix
definition at install time, so indeed it is liable to become stale with
Matrix updates ...

Not to derail Dirk's proposal for "Breaks", which could certainly have
uses beyond this particular example where a "correct" NAMESPACE directive
would solve the problems ...

Mikael

On 2023-08-07 6:00 am, r-devel-requ...@r-project.org wrote:
I would support this suggestion. There is a similar binary dependency chain from 
Matrix → TMB → glmmTMB; we have implemented various checks to make users aware 
that they need to reinstall from source, and to some extent we've tried to push 
out synchronous updates (i.e., push an update of TMB to CRAN every time Matrix 
changes, and an update of glmmTMB after that), but centralized machinery for 
this would certainly be nice. FWIW some of the machinery is here: 
https://github.com/glmmTMB/glmmTMB/blob/d9ee7b043281341429381faa19b5e53cb5a378c3/glmmTMB/R/utils.R#L209-L295 -- it relies on a Makefile rule that caches the current installed version of TMB: https://github.com/glmmTMB/glmmTMB/blob/d9ee7b043281341429381faa19b5e53cb5a378c3/glmmTMB/R/utils.R#L209-L295 cheers Ben Bolker On 2023-08-06 5:05 p.m., Dirk Eddelbuettel wrote:

CRAN, by relying on the powerful package management system that is part of R,
provides an unparalleled framework for extending R with nearly 20k packages.

We recently encountered an issue that highlights a missing element in the
otherwise outstanding package management system. So we would like to start a
discussion about enhancing its feature set. As shown below, a mechanism to
force reinstallation of packages may be needed.

A demo is included below, it is reproducible in a container. We find the
easiest/fastest reproduction is by saving the code snippet below in the
current directory as eg 'matrixIssue.R' and have it run in a container as

 docker run --rm -ti -v `pwd`:/mnt rocker/r2u Rscript /mnt/matrixIssue.R

This runs in under two minutes, first installing the older Matrix, next

installs SeuratObject, and then by removing the older Matrix making the
(already installed) current Matrix version the default. This simulates a
package update for Matrix. Which, as the final snippet demonstrates, silently
breaks SeuratObject as the cached S4 method Csparse_validate is now missing.
So when SeuratObject was installed under Matrix 1.5.1, it becomes unuseable
under Matrix 1.6.0.

What this shows is that a call to update.packages() will silently corrupt an
existing installation.  We understand that this was known and addressed at
CRAN by rebuilding all binary packages (for macOS and Windows).

But it leaves both users relying on source installation as well as
distributors of source packages in a dire situation. It hurt me three times:
my default R installation was affected with unit tests (involving
SeuratObject) silently failing. It similarly broke our CI setup at work.  And
it created a fairly bad headache for the Debian packaging I am involved with
(and I surmise it affects other distro similarly).

It would be good to have a mechanism where a package, when being upgraded,
could flag that 'more actions are required' by the system (administrator).
We think this example demonstrates that we need such a mechanism to avoid
(silently !!) breaking existing installations, possibly by forcing
reinstallation of other packages.  R knows the package dependency graph and
could trigger this, possibly after an 'opt-in' variable the user / admin
sets.

One possibility may be to add a new (versioned) field 'Breaks:'. Matrix could
then have added 'Breaks: SeuratObject (<= 4.1.3)' preventing an installation
of Matrix 1.6.0 when SeuratObject 4.1.3 (or earlier) is present, but
permitting an update to Matrix 1.6.0 alongside a new version, say, 4.1.4 of
SeuratObject which could itself have a versioned Depends: Matrix (>= 1.6.0).

Regards,  Dirk


## Code example follows. Recommended to run the rocker/r2u container.
## Could also run 'apt update -qq; apt upgrade -y' but not required
## Thanks to my colleague Paul Hoffman for the core of this example

## now have Matrix 1.6.0 because r2u and CRAN 

[Rd] proposal for WRE: clarify that use of S4 classes implies use of superclasses

2023-07-19 Thread Mikael Jagan

If a package has

importClassesFrom(P, C)

in its NAMESPACE, then should it _also_ have

importClassesFrom(P, )
importClassesFrom(Q, )
## and so on

... ?  I think that WRE could be more clear on this point, and in any case
I _think_ that the answer is yes.

Notably, I think that this rule would resolve some of the problems
with stale caches that I described in this thread from September:

https://stat.ethz.ch/pipermail/r-devel/2022-September/081971.html

I've attached a script demonstrating my point.  It creates and installs a
package named TestPackage with

importClassesFrom(Matrix, dgCMatrix, CsparseMatrix)

in NAMESPACE and

setClass("whatever", contains = "dgCMatrix")

in R/*.R.  After installing the package, I see:


> ns <- asNamespace("TestPackage")
> names(ns)
 [1] ".__C__generalMatrix"  ".__C__Matrix" ".__C__sparseMatrix"
 [4] ".__C__compMatrix" ".__C__whatever"   "zzz"
 [7] ".packageName" ".__C__dsparseMatrix"  ".__NAMESPACE__."
[10] ".__C__dMatrix"".__S3MethodsTable__."
> sort(names(ns))
 [1] ".__C__Matrix" ".__C__compMatrix" ".__C__dMatrix"
 [4] ".__C__dsparseMatrix"  ".__C__generalMatrix"  ".__C__sparseMatrix"
 [7] ".__C__whatever"   ".__NAMESPACE__."  ".__S3MethodsTable__."
[10] ".packageName" "zzz"
> sort(names(parent.env(ns)))
[1] ".__C__CsparseMatrix" ".__C__dgCMatrix" "setClass"


i.e., the imported classes are cached in the parent of the namespace (the
imports environment), and superclasses of dgCMatrix that are _not_ imported
are cached in the namespace itself.  The caching of superclasses does _not_
occur if I add all of the superclasses to the importClassesFrom directive
in NAMESPACE _or_ if I delete the call to setClass in R/*.R.

It is precisely these cached superclasses that are liable to become stale,
because, if I understand correctly, the namespace is populated and serialized
at _install_ time, whereas the imports environment is populated at _load_ time.

Hence by clarifying in WRE that packages should import exported superclasses
of classes that they extend, etc., we could stem some of the "staleness" on
CRAN ...

But maybe my analysis is mistaken, so I'll wait for comments from others ...

Mikaelpackage <- "TestPackage"
dir.create(file.path(package, "R"), recursive = TRUE)

cat(file = file.path(package, "DESCRIPTION"), "
Package: TestPackage
Version: 0.0-0
License: GPL (>= 2)
Description: A (one paragraph) description of what
  the package does and why it may be useful.
Title: My First Collection of Functions
Author: First Last [aut, cre]
Maintainer: First Last 
Imports: Matrix, methods
")

cat(file = file.path(package, "NAMESPACE"), "
export(zzz)
importFrom(methods, setClass)
importClassesFrom(Matrix, dgCMatrix, CsparseMatrix)
")

cat(file = file.path(package, "R", paste0(package, ".R")), "
zzz <- function() double(3L)
#setClass(\"whatever\", contains = \"dgCMatrix\")
")

tools:::Rcmd(c("build", package))
tools:::Rcmd(c("INSTALL", Sys.glob(paste0(package, "_*.tar.gz"

## unlink(Sys.glob(paste0(package, "*")), recursive = TRUE)
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] logic tweak needed for as.data.frame. deprecation warning

2023-07-06 Thread Mikael Jagan

Another issue raised in the earlier thread is that as.data.frame.POSIXlt
still calls as.data.frame.POSIXct.  Hence another path to a false positive
deprecation warning would be:

> Sys.setenv("_R_CHECK_AS_DATA_FRAME_EXPLICIT_METHOD_" = TRUE)
> as.data.frame(as.POSIXlt(.POSIXct(0, "UTC")))
  as.POSIXlt(.POSIXct(0, "UTC"))
1 1970-01-01
Warning message:
Direct call of 'as.data.frame.POSIXct()' is deprecated.  Use 
'as.data.frame.vector()' or 'as.data.frame()' instead


as.data.frame.POSIXlt could simply change to using as.data.frame.vector.

I glanced at the other non-deprecated as.data.frame. and did not
see other usage of the deprecated ones ... a more systematic check could
be worth doing.

Mikael

On 2023-07-06 11:32 am, Mikael Jagan wrote:

Continuing the thread started on R-package-devel, here:
https://stat.ethz.ch/pipermail/r-package-devel/2023q3/009307.html

The logic of the now soft-deprecated as.data.frame.,

  > body(as.data.frame.integer)[[2L]]
if ((sys.nframe() <= 1L || sys.call(-1L)[[1L]] != quote(as.data.frame)) &&
  nzchar(Sys.getenv("_R_CHECK_AS_DATA_FRAME_EXPLICIT_METHOD_")))
.Deprecated(msg = gettextf("Direct call of '%s()' is deprecated.  Use '%s()' or
'%s()' instead",
  "as.data.frame.integer", "as.data.frame.vector", "as.data.frame"))

may need adjustment to avoid false positives such as this one:

  > Sys.setenv("_R_CHECK_AS_DATA_FRAME_EXPLICIT_METHOD_" = TRUE)
  > f <- as.data.frame
  > f(0L)
0L
1  0
Warning message:
Direct call of 'as.data.frame.integer()' is deprecated.  Use
'as.data.frame.vector()' or 'as.data.frame()' instead

i.e., the condition sys.call(-1L)[[1L]] != quote(as.data.frame) is not precise
enough ... would !identical(sys.function(-1L), as.data.frame) work instead?

Mikael


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] logic tweak needed for as.data.frame. deprecation warning

2023-07-06 Thread Mikael Jagan

Continuing the thread started on R-package-devel, here:
https://stat.ethz.ch/pipermail/r-package-devel/2023q3/009307.html

The logic of the now soft-deprecated as.data.frame.,

> body(as.data.frame.integer)[[2L]]
if ((sys.nframe() <= 1L || sys.call(-1L)[[1L]] != quote(as.data.frame)) &&
nzchar(Sys.getenv("_R_CHECK_AS_DATA_FRAME_EXPLICIT_METHOD_"))) 
.Deprecated(msg = gettextf("Direct call of '%s()' is deprecated.  Use '%s()' or 
'%s()' instead",

"as.data.frame.integer", "as.data.frame.vector", "as.data.frame"))

may need adjustment to avoid false positives such as this one:

> Sys.setenv("_R_CHECK_AS_DATA_FRAME_EXPLICIT_METHOD_" = TRUE)
> f <- as.data.frame
> f(0L)
  0L
1  0
Warning message:
Direct call of 'as.data.frame.integer()' is deprecated.  Use 
'as.data.frame.vector()' or 'as.data.frame()' instead


i.e., the condition sys.call(-1L)[[1L]] != quote(as.data.frame) is not precise
enough ... would !identical(sys.function(-1L), as.data.frame) work instead?

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] New behavior when running script in package directory?

2023-06-21 Thread Mikael Jagan

Surely this behaviour is just a case of ESS being "too clever", sourcing
*.R files in special way when it detects that a file belongs to a package
(loading dependencies automatically, etc.)?

The function ss() is defined inside of .ess.source(), which is defined here:

https://github.com/emacs-ess/ESS/blob/5c4ae91cefa5c56fd13b204a9a996825af836a67/etc/ESSR/R/.basic.R#L168

If you think that there is a bug, then you could report it there ...

Mikael

On 2023-06-21 6:00 am, r-devel-requ...@r-project.org wrote:

When I run a script foo.R containing some trivial code in my home
directory, via Emacs/ESS, everything works as expected: R
starts, and a setwd() command to set the working directory is
run automatically before the code in the script is run.

But if I copy foo.R to some package/R directory strange
things happen. When I use Emacs/ESS to run the script
in its new location, R starts, and setwd() is called to set
the working directory, but then one or more libraries that the
package depends on are loaded, even though I am using no
libraries in foo.R.

Now consider foo.R that contains the following trivial code:
secsToRDateTime <- function(secs) {
   day2sec <- 60*60*24
   days <- secs/day2sec
}

When I try to run this from package/R I get...

Error in ss(file, echo = visibly, local = local, print.eval = output,  :
   /tmp/gpstime.R!CuSewT:2:0: unexpected end of input
1: secsToRDateTime <- function(secs) {
^

As I said, there are no problems when the script is run from my
home directory. This suggests that test scripts can no longer be
tested in a package's R directory?

Is this true?

Thanks,
Dominick


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] codetools wrongly complains about lazy evaluation in S4 methods

2023-06-15 Thread Mikael Jagan




On 2023-06-15 5:25 pm, Hervé Pagès wrote:

Oh but I see now that you've already tried this in your R/AllGenerics.R,
sorry for missing that, but that you worry about the following message
being disruptive on CRAN:

      The following object is masked from 'package:base':

      qr.X

Why would that be? As long as you only define methods for objects that
**you** control everything is fine. In other words you're not allowed to
define a method for "qr" objects because that method would override
base::qr.X(). But the generic itself and the method that you define for
your objects don't override anything so should not disrupt anything.



Yes, maybe it would be fine in principle, and of course many popular
packages emit startup messages.  Still, in practice, I think that
people are quite accustomed to library(Matrix) being "silent",
and probably a nontrivial fraction of our reverse dependencies would
encounter new NOTEs about differences between *.Rout and *.Rout.save,
etc.

The fraction of users who will ever call this method for qr.X is very
very small compared to the fraction who will be confused or annoyed
by the message.  Hence my hope that an implicit generic qr.X could
become part of package methods, notably as an implicit generic qr.R
already lives there ...

Or maybe there is a way for Matrix to define qr.X as an implicit generic
without creating other problems, but my experiments with setGenericImplicit
were not promising ...

Mikael


H.

On 6/15/23 13:51, Hervé Pagès wrote:


I'd argue that at the root of the problem is that your qr.X() generic
dispatches on all its arguments, including the 'ncol' argument which I
think the dispatch mechanism needs to evaluate **before** dispatch can
actually happen.

So yes lazy evaluation is a real feature but it does not play well for
arguments of a generic that are involved in the dispatch.

If you explicitly defined your generic with:

    setGeneric("qr.X", signature="qr")

you should be fine.

More generally speaking, it's a good idea to restrict the signature of
a generic to the arguments "that make sense". For unary operations
this is usually the 1st argument, for binary operations the first two
arguments etc... Additional arguments that control the operation like
modiflers, toggles, flags, rng seed, and other parameters, usually
have not place in the signature of the generic.

H.

On 6/14/23 20:57, Mikael Jagan wrote:

Thanks all - yes, I think that Simon's diagnosis ("user error") is
correct:
in this situation one should define a reasonable generic function
explicitly,
with a call to setGeneric, and not rely on the call inside of
setMethod ...

But it is still not clear what the way forward should be (for package
Matrix,
where we would like to export a method for 'qr.X').  If we do
nothing, then
there is the note, already mentioned:

     * checking R code for possible problems ... NOTE
     qr.X: no visible binding for global variable ‘R’
     Undefined global functions or variables:
   R

If we add the following to our R/AllGenerics.R :

     setGeneric("qr.X",
    function(qr, complete = FALSE, ncol, ...)
    standardGeneric("qr.X"),
    useAsDefault = function(qr, complete = FALSE, ncol,
...) {
    if(missing(ncol))
    base::qr.X(qr, complete = complete)
    else base::qr.X(qr, complete = complete, ncol = ncol)
    },
    signature = "qr")

then we get a startup message, which would be quite disruptive on CRAN :

     The following object is masked from 'package:base':

     qr.X

and if we further add setGenericImplicit("qr.X", restore = (TRUE|FALSE))
to our R/zzz.R, then for either value of 'restore' we encounter :

     ** testing if installed package can be loaded from temporary
location
     Error: package or namespace load failed for 'Matrix':
  Function found when exporting methods from the namespace
'Matrix' which is not S4 generic: 'qr.X'

Are there possibilities that I have missed?

It seems to me that the best option might be to define an implicit
generic
'qr.X' in methods via '.initImplicitGenerics' in
methods/R/makeBasicFunsList.R,
where I see that an implicit generic 'qr.R' is already defined ... ?

The patch pasted below "solves everything", though we'd still have to
think
about how to work for versions of R without the patch ...

Mikael

Index: src/library/methods/R/makeBasicFunsList.R
===
--- src/library/methods/R/makeBasicFunsList.R    (revision 84541)
+++ src/library/methods/R/makeBasicFunsList.R    (working copy)
@@ -263,6 +263,17 @@
     signature = "qr", where = where)
  setGenericImplicit("qr.R", where, FALSE)

+    setGeneric("qr.X",
+   function(qr, 

Re: [Rd] codetools wrongly complains about lazy evaluation in S4 methods

2023-06-14 Thread Mikael Jagan

Thanks all - yes, I think that Simon's diagnosis ("user error") is correct:
in this situation one should define a reasonable generic function explicitly,
with a call to setGeneric, and not rely on the call inside of setMethod ...

But it is still not clear what the way forward should be (for package Matrix,
where we would like to export a method for 'qr.X').  If we do nothing, then
there is the note, already mentioned:

* checking R code for possible problems ... NOTE
qr.X: no visible binding for global variable ‘R’
Undefined global functions or variables:
  R

If we add the following to our R/AllGenerics.R :

setGeneric("qr.X",
   function(qr, complete = FALSE, ncol, ...)
   standardGeneric("qr.X"),
   useAsDefault = function(qr, complete = FALSE, ncol, ...) {
   if(missing(ncol))
   base::qr.X(qr, complete = complete)
   else base::qr.X(qr, complete = complete, ncol = ncol)
   },
   signature = "qr")

then we get a startup message, which would be quite disruptive on CRAN :

The following object is masked from 'package:base':

qr.X

and if we further add setGenericImplicit("qr.X", restore = (TRUE|FALSE))
to our R/zzz.R, then for either value of 'restore' we encounter :

** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for 'Matrix':
 Function found when exporting methods from the namespace 'Matrix' which is 
not S4 generic: 'qr.X'


Are there possibilities that I have missed?

It seems to me that the best option might be to define an implicit generic
'qr.X' in methods via '.initImplicitGenerics' in methods/R/makeBasicFunsList.R,
where I see that an implicit generic 'qr.R' is already defined ... ?

The patch pasted below "solves everything", though we'd still have to think
about how to work for versions of R without the patch ...

Mikael

Index: src/library/methods/R/makeBasicFunsList.R
===
--- src/library/methods/R/makeBasicFunsList.R   (revision 84541)
+++ src/library/methods/R/makeBasicFunsList.R   (working copy)
@@ -263,6 +263,17 @@
   signature = "qr", where = where)
 setGenericImplicit("qr.R", where, FALSE)

+setGeneric("qr.X",
+   function(qr, complete = FALSE, ncol, ...)
+   standardGeneric("qr.X"),
+   useAsDefault = function(qr, complete = FALSE, ncol, ...) {
+   if(missing(ncol))
+   base::qr.X(qr, complete = complete)
+   else base::qr.X(qr, complete = complete, ncol = ncol)
+   },
+   signature = "qr", where = where)
+setGenericImplicit("qr.X", where, FALSE)
+
 ## our toeplitz() only has 'x'; want the generic "here" rather than "out 
there"

 setGeneric("toeplitz", function(x, ...) standardGeneric("toeplitz"),
   useAsDefault= function(x, ...) stats::toeplitz(x),

On 2023-06-13 8:01 pm, Simon Urbanek wrote:

I agree that this is not an R issue, but rather user error of not defining a 
proper generic so the check is right. Obviously, defining a generic with 
implementation-specific ncol default makes no sense at all, it should only be 
part of the method implementation. If one was to implement the same default 
behavior in the generic itself (not necessarily a good idea) the default would 
be ncol = if (complete) nrow(qr.R(qr, TRUE)) else min(dim(qr.R(qr, TRUE))) to 
not rely on the internals of the implementation.

Cheers,
Simon



On 14/06/2023, at 6:03 AM, Kasper Daniel Hansen  
wrote:

On Sat, Jun 3, 2023 at 11:51 AM Mikael Jagan  wrote:


The formals of the newly generic 'qr.X' are inherited from the non-generic
function in the base namespace.  Notably, the inherited default value of
formal argument 'ncol' relies on lazy evaluation:


formals(qr.X)[["ncol"]]

 if (complete) nrow(R) else min(dim(R))

where 'R' must be defined in the body of any method that might evaluate
'ncol'.



Perhaps I am misunderstanding something, but I think Mikael's expectations
about the scoping rules of R are wrong.  The enclosing environment of ncol
is where it was _defined_ not where it is _called_ (apologies if I am
messing up the computer science terminology here).

This suggests to me that codetools is right.  But a more extended example
would be useful. Perhaps there is something special with setOldClass()
which I am no aware of.

Also, Bioconductor has 100s of packages with S4 where codetools works well.

Kasper

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel





__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] codetools wrongly complains about lazy evaluation in S4 methods

2023-06-12 Thread Mikael Jagan

Thanks both.  Yes, I was aware of globalVariables, etc.  I guess I was hoping
to be pointed to the right place in the source code, in case the issue could
be addressed properly, notably as it seems to have already been addressed for
functions that are not S4 methods, i.e., codetools is apparently not bothered
by

def <- function(x = y) { y <- 0; x }

but still complains about

setMethod("someGeneric", "someClass", def)

...

Mikael

On 2023-06-07 5:13 am, Gabriel Becker wrote:

The API supported workaround is to call globalVariables, which,
essentially, declares the variables without defining them (a distinction R
does not usually make).

The issue with this approach, of course, is that its a very blunt
instrument. It will cause false negatives if you accidentally use the same
symbol in a standard evaluation context elsewhere in your code.
Nonetheless, that's the intended approach as far as i know.

Best,
~G



On Wed, Jun 7, 2023 at 1:07 AM Serguei Sokol via R-devel <
r-devel@r-project.org> wrote:


Le 03/06/2023 à 17:50, Mikael Jagan a écrit :

In a package, I define a method for not-yet-generic function 'qr.X'
like so:

 > setOldClass("qr")
 > setMethod("qr.X", signature(qr = "qr"), function(qr, complete,
ncol) NULL)

The formals of the newly generic 'qr.X' are inherited from the
non-generic
function in the base namespace.  Notably, the inherited default value of
formal argument 'ncol' relies on lazy evaluation:

 > formals(qr.X)[["ncol"]]
 if (complete) nrow(R) else min(dim(R))

where 'R' must be defined in the body of any method that might
evaluate 'ncol'.
To my surprise, tools:::.check_code_usage_in_package() complains about
the
undefined symbol:

 qr.X: no visible binding for global variable 'R'
 qr.X,qr: no visible binding for global variable 'R'
 Undefined global functions or variables:
   R

I think this issue is similar to the complaints about non defined
variables in expressions involving non standard evaluation, e.g. column
names in a data frame which are used as unquoted symbols. One of
workarounds is simply to declare them somewhere in your code. In your
case, it could be something as simple as:

R=NULL

Best,
Serguei.



I claim that it should _not_ complain, given that lazy evaluation is a
really
a feature of the language _and_ given that it already does not
complain about
the formals of functions that are not S4 methods.

Having said that, it is not obvious to me what in codetools would need
to change
here.  Any ideas?

I've attached a script that creates and installs a test package and
reproduces
the check output by calling tools:::.check_code_usage_in_package().
Hope it
gets through.

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel





__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Rd macros are not expanded inside of \eqn{} or \deqn{}

2023-06-12 Thread Mikael Jagan

I was a bit surprised to learn that, if one has an Rd file as below:

%% zzz.Rd
\newcommand{\zzz}{whatever}
\name{zzz}
\title{zzz}
\description{ \zzz{} \eqn{\zzz{}} \deqn{\zzz{}} }

then the macro is _not_ expanded inside of \eqn{} or \deqn{} when parsed to text
or HTML.  Is this behaviour intentional?  Could it be changed?  Inside of \eqn{}
and \deqn{} is where I am _most_ likely to want to use macros, at least since
R 4.2.0, which added KaTeX support ...

See output pasted below.

Mikael

> tools::Rd2txt(tools::parse_Rd("zzz.Rd"))
zzz

Description:

 whatever \zzz{}

   \zzz{}

> tools::Rd2HTML(tools::parse_Rd("zzz.Rd"))
R: zzz


href="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.css;>


const macros = { "\\R": "\\textsf{R}", "\\code": "\\texttt"};
function processMathHTML() {
var l = document.getElementsByClassName('reqn');
for (let e of l) { katex.render(e.textContent, e, { throwOnError: false, macros }); }
return;
}
https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.js";
onload="processMathHTML();">



zzzR 
Documentation


zzz

Description

 whatever \zzz{} 
\zzz{}






__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] codetools wrongly complains about lazy evaluation in S4 methods

2023-06-03 Thread Mikael Jagan

In a package, I define a method for not-yet-generic function 'qr.X' like so:

> setOldClass("qr")
> setMethod("qr.X", signature(qr = "qr"), function(qr, complete, ncol) NULL)

The formals of the newly generic 'qr.X' are inherited from the non-generic
function in the base namespace.  Notably, the inherited default value of
formal argument 'ncol' relies on lazy evaluation:

> formals(qr.X)[["ncol"]]
if (complete) nrow(R) else min(dim(R))

where 'R' must be defined in the body of any method that might evaluate 'ncol'.
To my surprise, tools:::.check_code_usage_in_package() complains about the
undefined symbol:

qr.X: no visible binding for global variable 'R'
qr.X,qr: no visible binding for global variable 'R'
Undefined global functions or variables:
  R

I claim that it should _not_ complain, given that lazy evaluation is a really
a feature of the language _and_ given that it already does not complain about
the formals of functions that are not S4 methods.

Having said that, it is not obvious to me what in codetools would need to change
here.  Any ideas?

I've attached a script that creates and installs a test package and reproduces
the check output by calling tools:::.check_code_usage_in_package().  Hope it
gets through.

Mikaelnm <- "TestPackage"
dir.create(tmp <- file.path(tempdir(), nm))
dir.create(file.path(tmp, "R"))

cat(file = file.path(tmp, "DESCRIPTION"), "
Package: TestPackage
Version: 0.0-0
License: GPL (>= 2)
Description: A (one paragraph) description of what
  the package does and why it may be useful.
Title: My First Collection of Functions
Author: First Last [aut, cre]
Maintainer: First Last 
Imports: methods
")

cat(file = file.path(tmp, "NAMESPACE"), "
importFrom(methods, setMethod, setOldClass)
exportMethods(qr.X)
export(xyz)
")

cat(file = file.path(tmp, "R", paste0(nm, ".R")), "
setOldClass(\"qr\")
setMethod(\"qr.X\", signature(qr = \"qr\"), function(qr, complete, ncol) NULL)
xyz <- function(x, y = z) { z <- 1; x + y }
")

install.packages(tmp, repos = NULL)
tools:::.check_code_usage_in_package(nm)
## qr.X: no visible binding for global variable 'R'
## qr.X,qr: no visible binding for global variable 'R'
## Undefined global functions or variables:
##   R

unloadNamespace(nm)
remove.packages(nm)
unlink(tmp)
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Change DEFAULTDEPARSE to DEFAULTDEPARSE | SHOWATTRIBUTES ?

2023-05-06 Thread Mikael Jagan

The deparse options used by default by 'deparse' and 'dput' are

c("keepNA", "keepInteger", "niceNames", "showAttributes")

but Defn.h still has

#define DEFAULTDEPARSE		1089 /* KEEPINTEGER | KEEPNA | NICE_NAMES, used for 
calls */


i.e., with the SHOWATTRIBUTES bit turned off.  Is that on purpose?
Note that this leads to weird things like:

> (expr <- call("is.matrix", matrix(1:4, 2L, 2L)))
is.matrix(1:4)
> eval(expr)
[1] TRUE

which can confuse anyone not paying close attention ...

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] sum(), min(), max(), prod() vs. named arguments in ...

2023-04-18 Thread Mikael Jagan





On 2023-04-15 6:00 am, r-devel-requ...@r-project.org wrote:

Date: Fri, 14 Apr 2023 13:38:00 +0300
From: Ivan Krylov
To:r-devel@r-project.org
Subject: [Rd] sum(), min(), max(), prod() vs. named arguments in ...

Message-ID: <20230414133800.75383dae-6792@arachnoid>

Content-Type: text/plain; charset="us-ascii"


Hello R-devel,

As mentioned on Fosstodon [1] and discussed during RCOH [2], named
arguments to sum(), min(), max() and prod() are currently processed the
same way as the un-named ones. Additionally, when specifying the na.rm
argument more than once, the last specified value is silently taken
into account.

Most of this behaviour is exactly as documented, but it's arguably a
source of mistakes when the na.rm=TRUE argument is mistyped and
converted to 1.

Internally, all these calls land in do_summary(), and the na.rm
argument is processed by fixup_NaRm(). mean() is safe because it's
dispatched via S3 lookup.

Do users normally name their arguments to sum()? If not, it could be
relatively safe to make it a warning to pass named arguments to sum()
that are not na.rm and later transition it to an error:



Forbidding or warning against tagged arguments other than 'na.rm' would be
quite intrusive, since it is not uncommon to see do.call(sum, ).


--- src/main/summary.c  (revision 84252)
+++ src/main/summary.c  (working copy)
@@ -419,6 +419,8 @@
na_value = CAR(a);
if(prev == R_NilValue) args = CDR(a);
else SETCDR(prev, CDR(a));
+   } else if (TAG(a) && TAG(a) != R_NilValue) {
+   warning("Named argument \"%s\" here is probably a mistake", 
CHAR(PRINTNAME(TAG(a;
}
prev = a;
  }

(Can TAG(a) ever be NULL or anything other than R_NilValue or a symbol
here? We'll probably need to translate this message, too.)

Passing na.rm more than once could be made into an error right away:



That would be much easier to support, as users should be accustomed to that
_not_ working.


--- src/main/summary.c  (revision 84252)
+++ src/main/summary.c  (working copy)
@@ -409,6 +409,7 @@
  attribute_hidden
  SEXP fixup_NaRm(SEXP args)
  {
+Rboolean seen_NaRm = FALSE;
  SEXP t, na_value;
  
  /* Need to make sure na.rm is last and exists */

@@ -415,7 +416,9 @@
  na_value = ScalarLogical(FALSE);
  for(SEXP a = args, prev = R_NilValue; a != R_NilValue; a = CDR(a)) {
if(TAG(a) == R_NaRmSymbol) {
+   if(seen_NaRm) error("Please specify na.rm only once");
+   seen_NaRm = TRUE;
if(CDR(a) == R_NilValue) return args;
na_value = CAR(a);
if(prev == R_NilValue) args = CDR(a);
else SETCDR(prev, CDR(a));

(Can we use error(_("formal argument \"%s\" matched by multiple actual
arguments"), "na.rm") to emit an already translated error message?)

Additionally, is it desirable to have S3 methods for sum() and its
friends? Currently, they are dispatched, but something confusing
happens to the arguments: according to the method, the dots contain
what I would expect them to contain (only the numbers to sum), but when
calling NextMethod() to compute the actual sum, extra arguments get
processed:

sum.foo <- function(..., ExtraArg = 999, na.rm = FALSE) {
  print(ExtraArg)
  str(...)
  NextMethod(generic = 'sum', ..., na.rm = na.rm)
}
sum(structure(100, class = 'foo'))
# [1] 999
#  'foo' num 100
# [1] 100
sum(structure(100, class = 'foo'), ExtraArg = -1)
# [1] -1
#  'foo' num 100 # <-- ExtraArg = -1 missing from ...
# [1] 99 # <-- but still subtracted



str(...) only gives the structure of the first argument matching the dots.
'ExtraArg' doesn't match the dots, as you say, but even if it did, it would
be discarded silently by 'str' there.  Better would be, e.g., str(list(...)).


Maybe I'm just misusing NextMethod(). This is probably not important in
practice due to how S3 dispatch works.



In both of your examples, just one named "actual" matches the "formal" '...'
in the call to 'NextMethod': the promise 'na.rm' evaluating to FALSE.

Named actuals matching the formal '...' are used to update the original call:

sum(structure(100, class = 'foo'))
==> sum(structure(100, class = 'foo'), na.rm = na.rm)

sum(structure(100, class = 'foo'), ExtraArg = -1)
==> sum(structure(100, class = 'foo'), ExtraArg = -1, na.rm = na.rm)

The new call is evaluated, this time dispatching the internal default method,
giving the results that you observed.

FWIW, help("NextMethod") does warn:

When a primitive is called as the default method, argument matching may
not work as described above due to the different semantics of primitives.

Mikael

-- Best regards, Ivan [1] https://fosstodon.org/@nibsalot/110105034507818285 [2] 
https://github.com/r-devel/rcontribution/blob/main/office_hours/2023-04-13_EMEA-APAC.md


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Time to add is.formula() to 'stats'?

2023-04-07 Thread Mikael Jagan

I know that it has been discussed in the past, but I wanted to ask
to revisit the idea of exporting

   is.formula <- function(x) inherits(x, "formula")

from 'stats', parallel to is.data.frame() in 'base', given how
widely formulae are used these days in conjunction with data frames,
even outside of model fitting functions (e.g., for split-apply).

One could argue that today data frames and formulae go hand in hand,
and that the lack of is.formula() is a rather ugly asymmetry ...

Furthermore, 'formula' is one of the only S3 classes generated by way
of a primitive (the `~` operator, calling do_tilde() in names.c), so
it is really in some sense "special" { compared to 'factor', 'POSIXlt',
etc. }.

What do people think?

In case it helps, I've gathered some data from 'base' and the so-called
'defaultPackages', reproduced by the attached R script ... see below.

Mikael





1. For which X does is.X() have no corresponding as.X()?

 [1] "R" "atomic""element"   "finite""hashtab"   "infinite"
 [7] "language"  "leaf"  "loaded""mts"   "na""nan"
[13] "object""primitive" "recursive" "tskernel"  "unsorted"

2. For which Y does as.Y() have no corresponding is.Y()?

 [1] "Date"  "POSIXct"   "POSIXlt"   "dendrogram"
 [5] "difftime"  "dist"  "formula"   "graphicsAnnot"
 [9] "hclust""hexmode"   "octmode"   "person"
[13] "personList""roman"

3. For which Z does is.Z() just call inherits(., "Z")?

[1] "data.frame"  "factor"  "numeric_version" "ordered"
[5] "package_version" "raster"  "relistable"  "table"
## all as.*() and is.*() in 'base' and 'defaultPackages'
pkg <- c("base", "datasets", "grDevices", "graphics",
 "methods", "stats", "utils")
getExports <- function(s) names(as.environment(paste0("package:", s)))
nms <- sort(unlist(lapply(pkg, getExports)))
as. <- nms[startsWith(nms, "as.")]
is. <- nms[startsWith(nms, "is.")]

## excluding methods and assignments
as.. <- c("as.data.frame", grep("([.].+[.]|<-)", as., value=TRUE, invert=TRUE))
is.. <- c("is.data.frame", grep("([.].+[.]|<-)", is., value=TRUE, invert=TRUE))

cl.as <- sub("^as[.]", "", as..)
cl.is <- sub("^is[.]", "", is..)

callsInherits <- function(x)
is.call(b <- body(match.fun(x))) && b[[1L]] == "inherits"

## missing as.*()
setdiff(cl.is, cl.as)
## missing is.*()
setdiff(cl.as, cl.is)
## is.*() just calling inherits()
cl.is[vapply(is.., callsInherits, NA)]
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] det(diag(c(NaN, 1))) should be NaN, not 0

2023-03-16 Thread Mikael Jagan

Hmm ... I can no longer reproduce this under r83996 when configuring
--without-lapack and --without-blas {the default}.  Now det(A), det(B),
det(C), and det(D) are all NaN.

I assume that the reason is the recent update to use LAPACK 3.11.0?
But I don't see any related NEWS here:

https://netlib.org/lapack/lapack-3.11.0.html

It is possible that the underlying issue in DGETRF (INFO>0 due to NaN
pivots rather than 0 pivots {=> singular}) still exists for matrices
less trivial than my 2-by-2 examples.  Will have to experiment ...

Mikael

On 2022-11-09 3:58 pm, Mikael Jagan wrote:

Hello,

Currently, determinant(A) calculates the determinant of 'A' by factorizing
A=LU and computing prod(diag(U)) [or the logarithm of the absolute value].
The factorization is done by LAPACK routine DGETRF, which gives a status
code INFO, documented [1] as follows:

*>  INFO is INTEGER
*>  = 0:  successful exit
*>  < 0:  if INFO = -i, the i-th argument had an illegal value
*>  > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
*>has been completed, but the factor U is exactly
*>singular, and division by zero will occur if it is used
*>to solve a system of equations.

Accordingly, when INF0>0, determinant(A) behaves as det(A)=0, _not_ computing
prod(diag(U)).  The problem here is that DGETRF can _also_ give positive
INFO for matrices containing NaN, which may very well not be singular for some
finite value of NaN.

I claim that, when INFO>0, determinant(A) should _not_ behave as det(A)=0
unconditionally, but rather sometimes (depending on some test) give NaN.
Here is one case where 0 is really "wrong":

  > (A <- diag(c(NaN, 1)))
   [,1] [,2]
[1,]  NaN0
[2,]01
  > det(A)
[1] 0

R isn't consistent, either:

  > (B <- diag(c(1, NaN)))
   [,1] [,2]
[1,]10
[2,]0  NaN
  > det(B)
[1] NaN

Here, DGETRF _does_ succeed, because it does not "see" the trailing NaN in 'B'.

So: Should R change to better handle the INFO>0 case?  If so, how?

Ideally (I think), the proposed change would give NaN for 'A' and 'B'
above and 0 for 'C' and 'D' below (both of which really _are_ singular):

  > (C <- matrix(c(NaN, NaN, 0, 0), 2L, 2L))
   [,1] [,2]
[1,]  NaN0
[2,]  NaN0
  > det(C)
[1] NaN
  > (D <- t(C))
   [,1] [,2]
[1,]  NaN  NaN
[2,]00
  > det(D)
[1] 0

Furthermore, the proposed change should _not_ decrease the performance
of determinant(A) for nonsingular 'A' ...

For those looking, the relevant C-level function is det_ge_real(),
defined in R-devel/src/modules/lapack/Lapack.c (at line 1260 in r83320).

Mikael

[1] https://github.com/Reference-LAPACK/lapack/blob/master/SRC/dgetrf.f


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Regenerate m4/gettext.m4 with updated AM_GNU_GETTEXT?

2023-02-16 Thread Mikael Jagan

Currently, m4/gettext.m4 contains an old version of Autoconf macro
AM_GNU_GETTEXT relying on internal symbols (e.g., _nl_expand_alias)
to detect broken implementations of GNU gettext.  System libraries
are searched for the internal symbols unconditionally, i.e., even
when linking against a static GNU libintl, resulting in the following
false positive in my config.log:


configure:53900: checking for GNU gettext in libintl
configure:53937: clang -o conftest  -g -O2 -Wall -pedantic 
-mmacosx-version-min=11.0 -arch arm64 -falign-functions=8 
-Wno-error=implicit-function-declaration -fPIC -DPCRE2_STATIC 
-I/usr/local/include -I/opt/R/arm64/include -I/usr/local/include 
-L/opt/R/arm64/lib -L/usr/local/lib conftest.c -L/usr/local/lib -lpcre2-8 -llzma 
-lbz2 -lz -licucore -ldl -lm -liconv /usr/local/lib/libintl.a 
/usr/local/lib/libiconv.a >&5

Undefined symbols for architecture arm64:
  "__nl_expand_alias", referenced from:
  _main in conftest-0e23fb.o
ld: symbol(s) not found for architecture arm64


AM_GNU_GETTEXT was revised in the GNU gettext sources ~6 years ago
to address this:


$ git log -1 b67399b
commit b67399b40bc5bf3165b09e6a095ec941d4b30a97
Author: Daiki Ueno 
Date:   Thu May 26 13:38:57 2016 +0900

m4: Rely less on internal symbols

* gettext-runtime/m4/gettext.m4 (AM_GNU_GETTEXT): Skip checks for the
internal symbols _nl_msg_cat_cntr, _nl_domain_bindings, and
_nl_expand_alias, if __GNU_GETTEXT_SUPPORTED_REVISION is defined.
Problem reported and fix suggested by Masanori Ogino in:
https://lists.gnu.org/archive/html/bug-gettext/2016-04/msg0.html
The rationale behind this is: (1) those symbol checks are for detecting
certain broken implementations, namely NetBSD and Solaris 7, and
(2) __GNU_GETTEXT_SUPPORTED_REVISION is not defined in those
implementations, while it is defined on compatible implementations, such
as musl-libc which doesn't have those internal symbols.


Can m4/gettext.m4 be regenerated from a sufficiently newer release
of GNU gettext, without major disruption?

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] solve.default(a, b) should not ignore names(dimnames(.))

2022-11-10 Thread Mikael Jagan




On 2022-11-10 1:10 pm, Mikael Jagan wrote:

Hello,

Currently, solve.default() is defined such that

  > identical(dimnames(solve.default(a, b)),
  list(dimnames(a)[[2L]], dimnames(b)[[2L]]))

is always TRUE, i.e., ignoring names(dimnames(a)) and names(dimnames(b)).
Hence we see:

  > a <- b <- diag(2L)
  > dimnames(a) <- list(A1 = c("a11", "a12"), A2 = c("a21", "a22"))
  > dimnames(b) <- list(B1 = c("b11", "b12"), B2 = c("b21", "b22"))
  > a
   A2
A1a21 a22
a11   1   0
a12   0   1
  > b
   B2
B1b21 b22
b11   1   0
b12   0   1
  > solve.default(a, b)
  b21 b22
a21   1   0
a22   0   1

I claim that solve.default() should be changed to instead give:

  > identical(dimnames(solve.default(a, b)),
  c(dimnames(a)[2L], dimnames(b)[2L]))

This would make solve.default() consistent with `%*%`, which
_does_ respect names(dimnames(.)) :

  > a %*% b
   B2
A1b21 b22
a11   1   0
a12   0   1

If others agree, then I would submit a minimal patch to the R-level
solve.default() in src/library/base/R/solve.R and to the C-level
La_solve() and La_solve_cmplx() in src/modules/lapack/Lapack.c ...



Well, taking a closer look, I see more related issues, which might
be considered simultaneously.  (Sorry if this is too much for one thread.)

* qr.solve(a, b) and solve.qr(qr(a), b) also ignore names(dimnames(.))

  > qr.solve(a, b)
  b21 b22
  a21   1   0
  a22   0   1
  > solve.qr(qr(a), b)
  b21 b22
  a21   1   0
  a22   0   1


* dimnames(qr.solve(a)) and dimnames(solve.qr(qr(a))) do not agree
  with dimnames(solve.default(a)), i.e., when 'b' is missing

  > solve.default(a)
  a11 a12
  a21   1   0
  a22   0   1
  > qr.solve(a)
  [,1] [,2]
  a2110
  a2201
  > solve.qr(qr(a))
  [,1] [,2]
  a2110
  a2201


* More controversially: qr.qy(qr, y) and qr.qty(qr, y) are currently
  documented as retaining the 'dimnames' of 'y', and they _do_.  But
  _conventionally_ the rownames of matrix products are taken from the
  first factor, in this case 'Q'.  It is not currently documented what
  the 'dimnames' of the implicitly stored 'Q' and 'R' factors should be,
  leading to inconsistencies like this:

  > a
   A2
  A1a21 a22
a11   1   0
a12   0   1
  > qr.Q(qr(a)) %*% qr.R(qr(a))
A2
 a21 a22
[1,]   1   0
[2,]   0   1

  Hence I propose to enforce {and partly document} the following:
  1. that Q=qr.Q(qr(X)) gets the rownames of X and NULL colnames
  2. that R=qr.R(qr(X)) gets the (permuted) colnames of X and NULL rownames
  3. that dimnames(qr.qy (qr(X), y)) <=> dimnames(  Q  %*% y)
  4. that dimnames(qr.qty(qr(X), y)) <=> dimnames(t(Q) %*% y)

  I'm not sure what the level of disruption on CRAN would be,
  but internal consistency here would certainly be nice ...


Mikael


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] solve.default(a, b) should not ignore names(dimnames(.))

2022-11-10 Thread Mikael Jagan

Hello,

Currently, solve.default() is defined such that

> identical(dimnames(solve.default(a, b)),
list(dimnames(a)[[2L]], dimnames(b)[[2L]]))

is always TRUE, i.e., ignoring names(dimnames(a)) and names(dimnames(b)).
Hence we see:

> a <- b <- diag(2L)
> dimnames(a) <- list(A1 = c("a11", "a12"), A2 = c("a21", "a22"))
> dimnames(b) <- list(B1 = c("b11", "b12"), B2 = c("b21", "b22"))
> a
 A2
A1a21 a22
  a11   1   0
  a12   0   1
> b
 B2
B1b21 b22
  b11   1   0
  b12   0   1
> solve.default(a, b)
b21 b22
a21   1   0
a22   0   1

I claim that solve.default() should be changed to instead give:

> identical(dimnames(solve.default(a, b)),
c(dimnames(a)[2L], dimnames(b)[2L]))

This would make solve.default() consistent with `%*%`, which
_does_ respect names(dimnames(.)) :

> a %*% b
 B2
A1b21 b22
  a11   1   0
  a12   0   1

If others agree, then I would submit a minimal patch to the R-level
solve.default() in src/library/base/R/solve.R and to the C-level
La_solve() and La_solve_cmplx() in src/modules/lapack/Lapack.c ...

Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] det(diag(c(NaN, 1))) should be NaN, not 0

2022-11-09 Thread Mikael Jagan

Hello,

Currently, determinant(A) calculates the determinant of 'A' by factorizing
A=LU and computing prod(diag(U)) [or the logarithm of the absolute value].
The factorization is done by LAPACK routine DGETRF, which gives a status
code INFO, documented [1] as follows:

*>  INFO is INTEGER
*>  = 0:  successful exit
*>  < 0:  if INFO = -i, the i-th argument had an illegal value
*>  > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
*>has been completed, but the factor U is exactly
*>singular, and division by zero will occur if it is used
*>to solve a system of equations.

Accordingly, when INF0>0, determinant(A) behaves as det(A)=0, _not_ computing
prod(diag(U)).  The problem here is that DGETRF can _also_ give positive
INFO for matrices containing NaN, which may very well not be singular for some
finite value of NaN.

I claim that, when INFO>0, determinant(A) should _not_ behave as det(A)=0
unconditionally, but rather sometimes (depending on some test) give NaN.
Here is one case where 0 is really "wrong":

> (A <- diag(c(NaN, 1)))
 [,1] [,2]
[1,]  NaN0
[2,]01
> det(A)
[1] 0

R isn't consistent, either:

> (B <- diag(c(1, NaN)))
 [,1] [,2]
[1,]10
[2,]0  NaN
> det(B)
[1] NaN

Here, DGETRF _does_ succeed, because it does not "see" the trailing NaN in 'B'.

So: Should R change to better handle the INFO>0 case?  If so, how?

Ideally (I think), the proposed change would give NaN for 'A' and 'B'
above and 0 for 'C' and 'D' below (both of which really _are_ singular):

> (C <- matrix(c(NaN, NaN, 0, 0), 2L, 2L))
 [,1] [,2]
[1,]  NaN0
[2,]  NaN0
> det(C)
[1] NaN
> (D <- t(C))
 [,1] [,2]
[1,]  NaN  NaN
[2,]00
> det(D)
[1] 0

Furthermore, the proposed change should _not_ decrease the performance
of determinant(A) for nonsingular 'A' ...

For those looking, the relevant C-level function is det_ge_real(),
defined in R-devel/src/modules/lapack/Lapack.c (at line 1260 in r83320).

Mikael

[1] https://github.com/Reference-LAPACK/lapack/blob/master/SRC/dgetrf.f

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[R-pkg-devel] CRAN index replaces ampersand in BugReports URL with HTML entity

2022-11-07 Thread Mikael Jagan

Hello,

It was raised on the Matrix bug tracker [1] that the BugReports URL
on the CRAN index [2] is broken.  The URL in our DESCRIPTION file [3]
is fine, but contains an ampersand, which is improperly replaced with
the corresponding HTML entity in the HTML sources of the index.

Hence this does not affect bug.report(package="Matrix"), but _does_
make our bug tracker inaccessible to people accustomed to visiting
the CRAN page for links.

Can this be repaired?

Mikael

[1] 
https://r-forge.r-project.org/tracker/?func=detail=6787_id=61=294
[2] https://cran.r-project.org/package=Matrix
[3] https://r-forge.r-project.org/tracker/?atid=294_id=61

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


[Rd] Should package version requirements assume installation from sources?

2022-09-13 Thread Mikael Jagan

[Arguably also appropriate for R-package-devel, but posted to R-devel
as the discussion is aimed primarily at "experts" ... ]

We, the authors of Matrix, have encountered a somewhat subtle issue
induced by caching of S4 classes and methods in package namespaces.

The namespaces of three reverse dependent packages (SeuratObject, conText,
mcmcsae) cache the formal definition of our virtual class Matrix (and some
subclasses).  For example:

> ns <- asNamespace("SeuratObject")
> grep("^[.]__C__.*Matrix$", names(ns), value = TRUE)
[1] ".__C__dMatrix"   ".__C__compMatrix"".__C__AnyMatrix"
[4] ".__C__generalMatrix" ".__C__CsparseMatrix" ".__C__sparseMatrix"
[7] ".__C__dsparseMatrix" ".__C__Matrix"

The cached definition (which includes a _validity method_) is obtained from
the version of Matrix available when the reverse dependent package was built
from sources.  For example, if SeuratObject was built under Matrix 1.4-1,
then we get:

> getValidity(ns$.__C__Matrix)
function (object)
{
if (!isTRUE(r <- .Call(Dim_validate, object, "Matrix")))
r
else .Call(dimNames_validate, object)
}



whereas if SeuratObject was built under Matrix >= 1.5-0, then we get:

> getValidity(ns$.__C__Matrix)
function (object)
.Call(Matrix_validate, object)



There are two "questions" here:

1.  The symbol 'Matrix_validate' is not defined until Matrix 1.5-0.
Is it necessary, for this reason alone, for SeuratObject to have
'Imports: Matrix (>= 1.5-0)'?  Or can SeuratObject continue using
'Imports: Matrix (>= 1.3-3)', at the risk of errors like

> Error: object 'Matrix_validate' not found

(as already seen here: https://stackoverflow.com/questions/73700130)?

Note that this error would not occur for anyone installing SeuratObject
from sources, unless they decide to _downgrade_ Matrix after doing so.
Hence this primarily concerns Windows and macOS where R users would
typically install a binary built by CRAN (i.e., not on their system).

We are aware that package TMB tests in .onLoad() that the current Matrix
version is equal to or greater than the version available at build time,
thus avoiding a "strict" version requirement, but do not want this practice
to spread ...

2.  For how long should Matrix retain the superceded 'Dim_validate' and
'dimNames_validate', in order to ensure that "stale" cached validity
methods continue to work?

We hope that this discussion will highlight the potential ramifications
of importing classes and methods from other packages, and having one's
classes and methods imported _by_ other packages, especially for version
requirements.

Mikael, Martin, and Doug

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Subsetting "dspMatrix" without coercion to "matrix"

2021-11-17 Thread Mikael Jagan
This seems entirely avoidable, given that there is a relatively simple 
formula for converting 2-ary indices [i,j] of S to 1-ary indices k of 
S[lower.tri(S, TRUE)]:


k <- i + round(0.5 * (2L * n - j) * (j - 1L)) # for i >= j


I ought to be slightly more precise here: _coercion_ is avoidable, 
because we can always map [i,j] to [k], but memory limits are not. 
Certainly S@x[k] cannot be arbitrarily long...


At the very least, it would be convenient if the subset were performed 
efficiently whenever dimensions would be dropped anyway:


* S[i, ] and S[, j] where i and j are vectors indexing exactly zero or 
one rows/columns

* S[i] where i is a matrix of the form cbind(i, j)

This would support, e.g., a memory-efficient 'apply' analogue without 
any need for MARGIN...


applySymmetric <- function(X, FUN, ..., simplify = TRUE, check = TRUE) {
  if (check && !isSymmetric(X)) {
stop("'X' is not a symmetric matrix.")
  }
  ## preprocessing
  ans <- vector("list", n)
  for (i in seq_len(n)) {
ans[[i]] <- forceAndCall(1L, FUN, S[i, ], ...)
  }
  ## postprocessing
  ans
}

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Subsetting "dspMatrix" without coercion to "matrix"

2021-11-17 Thread Mikael Jagan
Currently, the class for dense symmetric matrices in packed storage, 
"dspMatrix", inherits its subset (i.e., `[`) methods from the "Matrix" 
class. As a result, subsetting "dspMatrix" requires coercion to 
"matrix". If memory cannot be allocated for this "matrix", then an error 
results.


n <- 3L
x <- as.double(seq_len(choose(n + 1L, 2L)))
S <- new("dspMatrix", uplo = "L", x = x, Dim = c(n, n))

S[, 1L]
# Error: vector memory exhausted (limit reached?)

traceback()
# 10: .dsy2mat(dsp2dsy(from))
# 9: asMethod(object)
# 8: as(x, "matrix")
# 7: x[, j = j, drop = TRUE]
# 6: x[, j = j, drop = TRUE]
# 5: eval(call, parent.frame())
# 4: eval(call, parent.frame())
# 3: callGeneric(x, , j = j, drop = TRUE)
# 2: S[, 1L]
# 1: S[, 1L]

This seems entirely avoidable, given that there is a relatively simple 
formula for converting 2-ary indices [i,j] of S to 1-ary indices k of 
S[lower.tri(S, TRUE)]:


k <- i + round(0.5 * (2L * n - j) * (j - 1L)) # for i >= j

Has the implementation of `[` for class "dspMatrix" been discussed 
already elsewhere? If not, shall I report it to Bugzilla as a wishlist item?


FWIW, I encountered this problem while trying to coerce a large "dist" 
object to "dspMatrix", expecting that I would be able to safely subset 
the result:


setAs(from = "dist", to = "dspMatrix", function(from) {
  p <- length(from)
  if (p > 0L) {
n <- as.integer(round(0.5 * (1 + sqrt(1 + 8 * p # p = n*(n-1)/2
x <- double(p + n)
i <- 1L + c(0L, cumsum(n:2L))
x[-i] <- from
  } else {
n <- 1L
x <- 0
  }
  new("dspMatrix", uplo = "L", x = x, Dim = c(n, n))
})

But that attempt failed for a entirely different reason. For large 
enough n, I would hit a memory limit at the line:


x[-i] <- from

So I guess my second question is: what is problematic about this 
benign-seeming subset-assignment?


Mikael

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel