Re: [R] extract parts of a list before symbol

2023-05-25 Thread avi.e.gross
All true Jeff, but why do things the easy way! LOL!

My point was that various data structures, besides the list we started with,
store the names as an attribute. Yes, names(listname) works fine to extract
whatever parts they want. My original idea of using a data.frame was because
it creates names when they are absent.  

And you are correct that if the original list was not as shown with only all
items of length 1, converting to a data.frame fails.

>From what you say, it is a harder think to write a function that returns a
"name" for column N given a list. As you note, you get a null when there are
no names.  You get empty strings when one or more (but not all) have no
names. But it can be done.

The OP initially was looking at a way to get a text version of a variable
they could use using perhaps regular expressions to parse.  Of course that
is not as easy as just looking at the names attribute in one of several
ways. But it may help in a sense to deal with the cases mentioned above.
The problem is that str() does not return anything except to stdout so it
must be captured to do silly things.

> test <- list(a=3,b=5,c=11)

> str(test)
List of 3
 $ a: num 3
 $ b: num 5
 $ c: num 11

> str(test[1])
List of 1
 $ a: num 3

> str(test[2])
List of 1
 $ b: num 5

> str(list(a=1, 2, c=3))
List of 3
 $ a: num 1
 $  : num 2
 $ c: num 3

> str(list(1, 2, 3))
List of 3
 $ : num 1
 $ : num 2
 $ : num 3

> text <- str(list(a=1, 2, c=3)[1])
List of 1
 $ a: num 1

> text <- capture.output(str(list(a=1, 2, c=3)))
> text
[1] "List of 3"   " $ a: num 1" " $  : num 2" " $ c: num 3"
So you could use some imaginative code that extracts what you want. I
repeat, this is not a suggested way nor the best, just something that seems
to work:

> sub("(^[\\$ ]*)(\\w+|)(:.*$)", "\\2", text[2:length(text)])
[1] "a" ""  "c"

Obviously the first line of output needs to be removed as it does not fit
the pattern. 

Perhaps in this case a way less complex way is to use summary() rather than
str as it does return the output as text.

> summary(list(a=1, 2, c=3)) -> text
> text
  Length Class  Mode   
a 1  -none- numeric
  1  -none- numeric
c 1  -none- numeric

This puts the variable name, if any, at the start but parsing that is not
trivial as it is not plain text. 

Bottom line, try not to do things the hard way. Just carefully use names()
...

-Original Message-
From: R-help  On Behalf Of Jeff Newmiller
Sent: Thursday, May 25, 2023 10:32 PM
To: r-help@r-project.org
Subject: Re: [R] extract parts of a list before symbol

What a remarkable set of detours, Avi, all deriving apparently from a few
gaps in your understanding of R.

As Rolf said, "names(test)" is the answer.

a) Lists are vectors. They are not atomic vectors, but they are vectors, so
as.vector(test) is a no-op.

test <- list( a = 1, b = 2, c=3 )
attributes(test)
attributes(as.vector(test))

(Were you thinking of the unlist function? If so, there is no reason to
convert the value of the list to an atomic vector in order to look at the
value of an attribute of that list.)

b) Data frames are lists, with the additional constraint that all elements
have the same length, and that a names attribute and a row.names attribute
are both required. Converting a list to a data frame to get the names is
expensive in CPU cycles and breaks as soon as the list elements have a
variety of lengths.

c) All data in R is stored as vectors. Worrying about whether a data value
is a vector is pointless.

d) All objects can have attributes, including the name attribute. However,
not all objects must have a name attribute... including lists. Omitting a
name for any of the elements of a list in the constructor will lead to
having a zero-length character values in the name attribute where the names
were omitted. Omitting all names in the list constructor will cause no names
attribute to be created for that list.

test2 <- list( 1, 2, 3 )
attributes(test2)

e) The names() function returns the value of the names attribute. If that
attribute is missing, it returns NULL. For dataframes, the colnames function
is equivalent to the names function (I rarely use the colnames function).
For lists, colnames returns NULL... there are no "columns" in a list,
because there is no constraint on the (lengths of the) contents of a list.

names(test2)

f) The names attribute, if it exists, is just a character vector. It is
never necessary to convert the output of names() to a character vector. If
the names attribute doesn't exist, then it is up to the user to write code
that creates it.

names(test2) <- c( "A", "B", "C" )
attributes(test2)
names(test2)
# or use the argument names in the list function

names(test2) <- 1:3 # integer
names(test2) # character
attributes(test2)$names <- 1:3 # integer
attributes(test2) # character
test2[[ "2" ]] == 2  # TRUE
test2$`2`  == 2 # TRUE



On May 25, 2023 6:17:37 PM PDT, avi.e.gr...@gmail.com wrote:
>Evan,
>
>List names are less easy than data.frame column names so 

Re: [R] extract parts of a list before symbol

2023-05-25 Thread Jeff Newmiller
What a remarkable set of detours, Avi, all deriving apparently from a few gaps 
in your understanding of R.

As Rolf said, "names(test)" is the answer.

a) Lists are vectors. They are not atomic vectors, but they are vectors, so 
as.vector(test) is a no-op.

test <- list( a = 1, b = 2, c=3 )
attributes(test)
attributes(as.vector(test))

(Were you thinking of the unlist function? If so, there is no reason to convert 
the value of the list to an atomic vector in order to look at the value of an 
attribute of that list.)

b) Data frames are lists, with the additional constraint that all elements have 
the same length, and that a names attribute and a row.names attribute are both 
required. Converting a list to a data frame to get the names is expensive in 
CPU cycles and breaks as soon as the list elements have a variety of lengths.

c) All data in R is stored as vectors. Worrying about whether a data value is a 
vector is pointless.

d) All objects can have attributes, including the name attribute. However, not 
all objects must have a name attribute... including lists. Omitting a name for 
any of the elements of a list in the constructor will lead to having a 
zero-length character values in the name attribute where the names were 
omitted. Omitting all names in the list constructor will cause no names 
attribute to be created for that list.

test2 <- list( 1, 2, 3 )
attributes(test2)

e) The names() function returns the value of the names attribute. If that 
attribute is missing, it returns NULL. For dataframes, the colnames function is 
equivalent to the names function (I rarely use the colnames function). For 
lists, colnames returns NULL... there are no "columns" in a list, because there 
is no constraint on the (lengths of the) contents of a list.

names(test2)

f) The names attribute, if it exists, is just a character vector. It is never 
necessary to convert the output of names() to a character vector. If the names 
attribute doesn't exist, then it is up to the user to write code that creates 
it.

names(test2) <- c( "A", "B", "C" )
attributes(test2)
names(test2)
# or use the argument names in the list function

names(test2) <- 1:3 # integer
names(test2) # character
attributes(test2)$names <- 1:3 # integer
attributes(test2) # character
test2[[ "2" ]] == 2  # TRUE
test2$`2`  == 2 # TRUE



On May 25, 2023 6:17:37 PM PDT, avi.e.gr...@gmail.com wrote:
>Evan,
>
>List names are less easy than data.frame column names so try this:
>
>> test <- list(a=3,b=5,c=11)
>> colnames(test)
>NULL
>> colnames(as.data.frame(test))
>[1] "a" "b" "c"
>
>But note an entry with no name has one made up for it.
>
>
>> test2 <- list(a=3,b=5, 666, c=11)
>> colnames(data.frame(test2))
>[1] "a""b""X666" "c"   
>
>But that may be overkill as simply converting to a vector if ALL parts are
>of the same type will work too:
>
>> names(as.vector(test))
>[1] "a" "b" "c"
>
>To get one at a time:
>
>> names(as.vector(test))[1]
>[1] "a"
>
>You can do it even simple by looking at the attributes of your list:
>
>> attributes(test)
>$names
>[1] "a" "b" "c"
>
>> attributes(test)$names
>[1] "a" "b" "c"
>> attributes(test)$names[3]
>[1] "c"
>
>
>-Original Message-
>From: R-help  On Behalf Of Evan Cooch
>Sent: Thursday, May 25, 2023 1:30 PM
>To: r-help@r-project.org
>Subject: [R] extract parts of a list before symbol
>
>Suppose I have the following list:
>
>test <- list(a=3,b=5,c=11)
>
>I'm trying to figure out how to extract the characters to the left of 
>the equal sign (i.e., I want to extract a list of the variable names, a, 
>b and c.
>
>I've tried the permutations I know of involving sub - things like 
>sub("\\=.*", "", test), but no matter what I try, sub keeps returning 
>(3, 5, 11). In other words, even though I'm trying to extract the 
>'stuff' before the = sign, I seem to be successful only at grabbing the 
>stuff after the equal sign.
>
>Pointers to the obvious fix? Thanks...
>
>__
>R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>and provide commented, minimal, self-contained, reproducible code.
>
>__
>R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>and provide commented, minimal, self-contained, reproducible code.

-- 
Sent from my phone. Please excuse my brevity.

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


Re: [R] extract parts of a list before symbol

2023-05-25 Thread avi.e.gross
Evan,

List names are less easy than data.frame column names so try this:

> test <- list(a=3,b=5,c=11)
> colnames(test)
NULL
> colnames(as.data.frame(test))
[1] "a" "b" "c"

But note an entry with no name has one made up for it.


> test2 <- list(a=3,b=5, 666, c=11)
> colnames(data.frame(test2))
[1] "a""b""X666" "c"   

But that may be overkill as simply converting to a vector if ALL parts are
of the same type will work too:

> names(as.vector(test))
[1] "a" "b" "c"

To get one at a time:

> names(as.vector(test))[1]
[1] "a"

You can do it even simple by looking at the attributes of your list:

> attributes(test)
$names
[1] "a" "b" "c"

> attributes(test)$names
[1] "a" "b" "c"
> attributes(test)$names[3]
[1] "c"


-Original Message-
From: R-help  On Behalf Of Evan Cooch
Sent: Thursday, May 25, 2023 1:30 PM
To: r-help@r-project.org
Subject: [R] extract parts of a list before symbol

Suppose I have the following list:

test <- list(a=3,b=5,c=11)

I'm trying to figure out how to extract the characters to the left of 
the equal sign (i.e., I want to extract a list of the variable names, a, 
b and c.

I've tried the permutations I know of involving sub - things like 
sub("\\=.*", "", test), but no matter what I try, sub keeps returning 
(3, 5, 11). In other words, even though I'm trying to extract the 
'stuff' before the = sign, I seem to be successful only at grabbing the 
stuff after the equal sign.

Pointers to the obvious fix? Thanks...

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

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


Re: [R] extract parts of a list before symbol

2023-05-25 Thread Rolf Turner
On Thu, 25 May 2023 13:29:52 -0400
Evan Cooch  wrote:

> Suppose I have the following list:
> 
> test <- list(a=3,b=5,c=11)
> 
> I'm trying to figure out how to extract the characters to the left of 
> the equal sign (i.e., I want to extract a list of the variable names,
> a, b and c.
> 
> I've tried the permutations I know of involving sub - things like 
> sub("\\=.*", "", test), but no matter what I try, sub keeps returning 
> (3, 5, 11). In other words, even though I'm trying to extract the 
> 'stuff' before the = sign, I seem to be successful only at grabbing
> the stuff after the equal sign.
> 
> Pointers to the obvious fix? Thanks...

Perhaps names(test) ???

cheers,

Rolf Turner

-- 
Honorary Research Fellow
Department of Statistics
University of Auckland
Stats. Dep't. (secretaries) phone:
 +64-9-373-7599 ext. 89622
Home phone: +64-9-480-4619

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


[ESS] brms / cmdstanr crashes in emacs but not terminal

2023-05-25 Thread Joshua Wiley via ESS-help
Hi All,

I normally work in Emacs (28.2 build 2)) on Windows 11 pro as an admin user.
Quite a few of my analyses these days use Stan (via cmdstanr and the brms
package as example).
I upgraded R to 4.3.0 and Stan. Now, I am quite reliably getting crashes
where my R process terminates when using Stan. For those not familiar, Stan
is in C++ and generates code which is then compiled into a custom C++ model
for that Bayesian analysis. The compilation is fine, but when it starts
sampling, I get this when I run via Emacs:

## Start sampling
## > >
## Process R finished at Fri May 26 10:32:05 2023

The reason I'm asking here and not just on Stan forums is that when I start
a terminal (cmd.exe) and start R there and run the exact same code, it
reliably finishes and does not crash.

I also tried M-x shell in Emacs and running R through that and also get a
crash.

If anyone knows a solution that would be great but at this stage I'd love
to hear even just ideas on _what_ the difference is? I guess in my head R
through terminal and R through Emacs were the same and so I'm not sure
where to even begin looking for causes.

Many thanks,

Josh

[[alternative HTML version deleted]]

__
ESS-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/ess-help


Re: [R] environments: functions within functions

2023-05-25 Thread Sarah Goslee
Thank you to both Duncan and Ivan for the detailed answers. I'll point
the mixR maintainer at this thread in the list archive, because your
suggestions were so clear, and I can't explain them as thoroughly.

I'll keep using x as the argument name for now.

Much appreciated,
Sarah

On Thu, May 25, 2023 at 10:18 AM Sarah Goslee  wrote:
>
> Hi,
>
> I ran into a problem with S3 method dispatch and scoping while trying
> to use functions from the mixR package within my own functions. I know
> enough to find the problem (I think!), but not enough to fix it
> myself. The problem isn't really a package-specific problem, so I'm
> starting here, and will file an issue with the maintainer once I have
> a solution.
>
> Detailed explanation below, but briefly, the S3 methods in this
> package use match.call() and then eval() to select the correct
> internal method. This works fine from the command line, but if the
> method is called from within another function, the use of
> environment() within eval() means that the objects passed to the
> wrapper function are no longer visible within the eval() call.
>
> I have a two-part question:
> A. How do I get around this right now?
> B. What would the correct approach be for the package authors?
>
> library(mixR)
>
> # first example from ?mixfit
> ## fitting the normal mixture models
> set.seed(103)
> x <- rmixnormal(200, c(0.3, 0.7), c(2, 5), c(1, 1))
> data <- bin(x, seq(-1, 8, 0.25))
> fit1 <- mixfit(x, ncomp = 2)  # raw data
> rm(x, data)
> ###
>
> # simple function
> funworks <- function(x) {
> print(x)
> }
>
> ###
>
> # almost identical simple function
> funfails <- function(thisx) {
> print(thisx)
> }
>
> ###
>
> funworks(fit1)
> funfails(fit1)
>
> ###
>
> The explanation as I understand it...
>
> print called on this object gets passed to print.mixfitEM(), which is:
>
>
> function (x, digits = getOption("digits"), ...)
> {
> family <- x$family
> mc <- match.call()
> mc$digits <- digits
> fun.name <- paste0("print", family)
> mc[[1]] <- as.name(fun.name)
> eval(mc, environment())
> }
>
>
> Working through the calls, when eval() is called from within funfails(), mc is
> printnormal(x = thisx, digits = 7)
> and the calling environment does not contain thisx.
>
> In funworks(), it's
> printnormal(x = x, digits = 7)
>
> and x is found.
>
> So, I can get around the problem by naming my argument x, as in
> funworks(), but that's unsatisfying. Is there something else I can do
> to get my functions to work?
>
> And what's the correct way to do what print.mixfitEM() is doing, so
> that it works regardless? I poked around for a while, but didn't find
> a clear (to me!) answer.
>
> Thanks,
> Sarah
>
> --
> Sarah Goslee (she/her)
> http://www.numberwright.com



-- 
Sarah Goslee (she/her)
http://www.numberwright.com

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


[R] extract parts of a list before symbol

2023-05-25 Thread Evan Cooch

Suppose I have the following list:

test <- list(a=3,b=5,c=11)

I'm trying to figure out how to extract the characters to the left of 
the equal sign (i.e., I want to extract a list of the variable names, a, 
b and c.


I've tried the permutations I know of involving sub - things like 
sub("\\=.*", "", test), but no matter what I try, sub keeps returning 
(3, 5, 11). In other words, even though I'm trying to extract the 
'stuff' before the = sign, I seem to be successful only at grabbing the 
stuff after the equal sign.


Pointers to the obvious fix? Thanks...

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


Re: [R] data.frame with a column containing an array

2023-05-25 Thread Jeff Newmiller
Maybe... if you want it to act like a matrix... then you should... use a 
matrix...

I think making this behaviour work with 2d arrays could be a feature, but 
making it work with higher dimension arrays would be difficult, and 
differentiating between 2d and higher dimension arrays could have just as 
unexpected behaviors as differentiating between matrices and 2d arrays is for 
you now.

Arrays and matrices are supposed to be more compatible now than they used to 
be... specifying a matrix should work just as well as specifying a 2d array 
when it comes to whatever operations are leading you to want an array at all, 
and will close the door on trying to stuff a higher dimension array into the 
dataframe accidentally.

... or don't put it into a data frame?

On May 25, 2023 10:15:00 AM PDT, Bert Gunter  wrote:
>I really don't know. I would call it a request for extended capabilities of
>[.data.frame, rather than a feature or bug. But maybe wiser heads than mine
>who monitor this list can sort it out.
>
>-- Bert
>
>On Wed, May 24, 2023 at 8:52 PM Georg Kindermann 
>wrote:
>
>> So is this an expected behavior or is it a bug which should be reported
>> somewhere else?
>>
>> Thanks!
>> Georg
>>
>>
>>
>> Gesendet: Dienstag, 09. Mai 2023 um 19:28 Uhr
>> Von: "Bert Gunter" 
>> An: "Georg Kindermann" 
>> Cc: "Rui Barradas" , r-help@r-project.org
>> Betreff: Re: [R] data.frame with a column containing an array
>>
>>
>>
>> I think the following may provide a clearer explanation:
>>
>> subs <- c(1,3)
>> DFA <- data.frame(id = 1:3)
>> ar <- array(1:12, c(3,2,2))
>> ## yielding
>> > ar
>> , , 1
>>
>>  [,1] [,2]
>> [1,]14
>> [2,]25
>> [3,]36
>>
>> , , 2
>>
>>  [,1] [,2]
>> [1,]7   10
>> [2,]8   11
>> [3,]9   12
>>
>> ## array subscripting gives
>> > ar[subs,,]
>> , , 1
>>
>>  [,1] [,2]
>> [1,]14
>> [2,]36
>>
>> , , 2
>>
>>  [,1] [,2]
>> [1,]7   10
>> [2,]9   12
>>
>> ## Now with df's
>> > DFA[["ar"]] <- ar
>> >
>> > DFM <- data.frame(id = 1:3)
>> > DFM[["M"]] <- matrix(1:6, nc =2)
>> >
>> > str(DFM)
>> 'data.frame': 3 obs. of  2 variables:
>>  $ id: int  1 2 3
>>  $ M : int [1:3, 1:2] 1 2 3 4 5 6
>> > str(DFA)
>> 'data.frame': 3 obs. of  2 variables:
>>  $ id: int  1 2 3
>>  $ ar: int [1:3, 1:2, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
>> >
>> > ## But the data frame print method for these give
>> > DFM
>>   id M.1 M.2
>> 1  1   1   4
>> 2  2   2   5
>> 3  3   3   6
>> > DFA
>>   id ar.1 ar.2 ar.3 ar.4
>> 1  1147   10
>> 2  2258   11
>> 3  3369   12
>> >
>> > ## [.data.frame subscripting gives
>> > DFA[subs,]
>>   id ar
>> 1  1  1
>> 3  3  3
>> > DFM[subs,]
>>   id M.1 M.2
>> 1  1   1   4
>> 3  3   3   6
>> >
>> > ## but  explicit array subscripting of course works
>> > DFA$ar[match(subs,DFA$id),,]
>> , , 1
>>
>>  [,1] [,2]
>> [1,]14
>> [2,]36
>>
>> , , 2
>>
>>  [,1] [,2]
>> [1,]7   10
>> [2,]9   12
>>
>>
>> Cheers,
>> Bert
>>
>
>   [[alternative HTML version deleted]]
>
>__
>R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>and provide commented, minimal, self-contained, reproducible code.

-- 
Sent from my phone. Please excuse my brevity.

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


Re: [R] data.frame with a column containing an array

2023-05-25 Thread Bert Gunter
I really don't know. I would call it a request for extended capabilities of
[.data.frame, rather than a feature or bug. But maybe wiser heads than mine
who monitor this list can sort it out.

-- Bert

On Wed, May 24, 2023 at 8:52 PM Georg Kindermann 
wrote:

> So is this an expected behavior or is it a bug which should be reported
> somewhere else?
>
> Thanks!
> Georg
>
>
>
> Gesendet: Dienstag, 09. Mai 2023 um 19:28 Uhr
> Von: "Bert Gunter" 
> An: "Georg Kindermann" 
> Cc: "Rui Barradas" , r-help@r-project.org
> Betreff: Re: [R] data.frame with a column containing an array
>
>
>
> I think the following may provide a clearer explanation:
>
> subs <- c(1,3)
> DFA <- data.frame(id = 1:3)
> ar <- array(1:12, c(3,2,2))
> ## yielding
> > ar
> , , 1
>
>  [,1] [,2]
> [1,]14
> [2,]25
> [3,]36
>
> , , 2
>
>  [,1] [,2]
> [1,]7   10
> [2,]8   11
> [3,]9   12
>
> ## array subscripting gives
> > ar[subs,,]
> , , 1
>
>  [,1] [,2]
> [1,]14
> [2,]36
>
> , , 2
>
>  [,1] [,2]
> [1,]7   10
> [2,]9   12
>
> ## Now with df's
> > DFA[["ar"]] <- ar
> >
> > DFM <- data.frame(id = 1:3)
> > DFM[["M"]] <- matrix(1:6, nc =2)
> >
> > str(DFM)
> 'data.frame': 3 obs. of  2 variables:
>  $ id: int  1 2 3
>  $ M : int [1:3, 1:2] 1 2 3 4 5 6
> > str(DFA)
> 'data.frame': 3 obs. of  2 variables:
>  $ id: int  1 2 3
>  $ ar: int [1:3, 1:2, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
> >
> > ## But the data frame print method for these give
> > DFM
>   id M.1 M.2
> 1  1   1   4
> 2  2   2   5
> 3  3   3   6
> > DFA
>   id ar.1 ar.2 ar.3 ar.4
> 1  1147   10
> 2  2258   11
> 3  3369   12
> >
> > ## [.data.frame subscripting gives
> > DFA[subs,]
>   id ar
> 1  1  1
> 3  3  3
> > DFM[subs,]
>   id M.1 M.2
> 1  1   1   4
> 3  3   3   6
> >
> > ## but  explicit array subscripting of course works
> > DFA$ar[match(subs,DFA$id),,]
> , , 1
>
>  [,1] [,2]
> [1,]14
> [2,]36
>
> , , 2
>
>  [,1] [,2]
> [1,]7   10
> [2,]9   12
>
>
> Cheers,
> Bert
>

[[alternative HTML version deleted]]

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


Re: [R] environments: functions within functions

2023-05-25 Thread Ivan Krylov
(Sorry for the double post.)

В Thu, 25 May 2023 18:53:45 +0300
Ivan Krylov  пишет:

> print(fit1) # tracer not called

Interesting. There must be some caching involved. If print(a) is
resolved to print.mixfitEM at least once, it keeps failing. In a fresh
R session, where a trace()-patch is done before printing objects of
this class, print(a) succeeds:

trace(mixR:::print.mixfitEM, quote({ mc$x <- x }), at = 7)
(function(a) print(a))(fit1) # this used to fail
# Tracing print.mixfitEM(a) step 7
# Normal mixture model with 2 components
#comp1 comp2
# pi 0.292 0.708
# mu 2.0140197 4.9837052
# sd 0.8896020 1.0273591
# 
# EM iterations: 78 AIC: 759.35 BIC: 775.84 log-likelihood: -374.67

-- 
Best regards,
Ivan

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


Re: [R] environments: functions within functions

2023-05-25 Thread Ivan Krylov
В Thu, 25 May 2023 10:18:13 -0400
Sarah Goslee  пишет:

> print called on this object gets passed to print.mixfitEM(), which is:
> 
> 
> function (x, digits = getOption("digits"), ...)
> {
> family <- x$family
> mc <- match.call()
> mc$digits <- digits
> fun.name <- paste0("print", family)
> mc[[1]] <- as.name(fun.name)
> eval(mc, environment())
> }
> 
> 
> Working through the calls, when eval() is called from within
> funfails(), mc is printnormal(x = thisx, digits = 7)
> and the calling environment does not contain thisx.

Your functions, both funworks and funfails, did nothing wrong. They are
using R as intended, so there shouldn't be anything to fix. I think that
mixR::mixfitEM is making a mistake in its use of non-standard
evaluation.

When working with match.call(), the typical pattern is to eval() the
modified call in the parent.frame() (where the call had originated and
where, presumably, all its referenced variables still live). mixR
cannot use this pattern unaltered because they want to call an
unexported function, e.g., mixR:::printnormal. The authors could
construct a call to ::: and insert that into mc[[1]] instead of
as.name(fun.name), so that the resulting call would be to
mixR:::printnormal(remaining arguments) and would thus cleanly evaluate
in the calling environment, but R CMD check could give them a NOTE for
using ::: (even with their own package).

One way to get around this would be to put the function itself in the
first element of the call (i.e. mc[[1]] <- get(fun.name) instead of
as.name(fun.name)), thus also making it possible to perform the call
despite as.name(fun.name) cannot be resolved from parent.frame(). This
could lead to scary-looking tracebacks.

Another way would be to keep the environment of the call as it is, but
evaluate the arguments from the matched call, something like:

for (i in seq_along(mc)[-1]) mc[[i]] <- eval(mc[[i]], parent.frame())

This code is untested, but the idea is to remove any dependency of the
matched call on the calling frame, thus making it possible to evaluate
it without problems in the package environment. This will again lead to
scary-looking tracebacks, potentially worse than the previous option
(depending on whether deparse() is longer for mixR:::printnormal or its
typical arguments), and will also wreak havoc on any additional use of
non-standard evaluation by printnormal (hopefully there isn't any, but
any arguments that should have stayed quoted will be evaluated instead).
They already do something like this with the digits=... argument.

I could also suggest a redesign of the package to make fuller use of
the S3 dispatch system (i.e. prepend x$family to class(x), possibly
with a package-specific prefix and make printnormal() and friends into
S3 methods for print()) instead of trying to implement it oneself, but
I understand that it may be not an available option.

I was going to suggest patching around the bug using trace(), but it
doesn't seem to work well with S3 method dispatch. No matter what I do,
UseMethod() seems to pick up the original definition of
mixR:::print.mixfitEM instead of the trace()-altered version:

trace(mixR:::print.mixfitEM, quote({ mc$x <- x }), at = 7)
mixR:::print.mixfitEM(fit1) # works as expected, but that doesn't matter
print(fit1) # tracer not called

-- 
Best regards,
Ivan

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


Re: [R] environments: functions within functions

2023-05-25 Thread Duncan Murdoch

On 25/05/2023 10:18 a.m., Sarah Goslee wrote:

Hi,

I ran into a problem with S3 method dispatch and scoping while trying
to use functions from the mixR package within my own functions. I know
enough to find the problem (I think!), but not enough to fix it
myself. The problem isn't really a package-specific problem, so I'm
starting here, and will file an issue with the maintainer once I have
a solution.

Detailed explanation below, but briefly, the S3 methods in this
package use match.call() and then eval() to select the correct
internal method. This works fine from the command line, but if the
method is called from within another function, the use of
environment() within eval() means that the objects passed to the
wrapper function are no longer visible within the eval() call.

I have a two-part question:
A. How do I get around this right now?
B. What would the correct approach be for the package authors?


I'll try B first.  The problem is that they want to look up fun.name in 
the environment that is visible from  print.mixfitEM(), i.e. the mixR 
internal namespace environment, and they also want to evaluate that 
function the way it was evaluated when print.mixfitEM was called, i.e. 
in parent.frame().  R doesn't support that kind of thing in one step, so 
they should do it in two steps, e.g. rewriting print.mixfitEM something 
like this:


function (x, digits = getOption("digits"), ...)
{
family <- x$family
mc <- match.call()
mc$digits <- digits
fun.name <- paste0("print", family)
e <- new.env(parent = parent.frame())
e[[fun.name]] <- get(fun.name)
mc[[1]] <- as.name(fun.name)
eval(mc, e)
}

This tries to get the function ("printnormal") from the local evaluation 
environment, but there's nothing there named "printnormal", so it goes 
to the parent environment, and gets it there.  It puts it in a new 
environment whose parent is parent.frame() and everything works.


For part A of your question, I can't think of any workaround other than 
using x as the name of the variable that is passed to print().  You 
could hide that fact by making a local function to do it, e.g.


  myprint <- function(x) print(x)

and then calling myprint(fit1).

Duncan Murdoch




library(mixR)

# first example from ?mixfit
## fitting the normal mixture models
set.seed(103)
x <- rmixnormal(200, c(0.3, 0.7), c(2, 5), c(1, 1))
data <- bin(x, seq(-1, 8, 0.25))
fit1 <- mixfit(x, ncomp = 2)  # raw data
rm(x, data)
###

# simple function
funworks <- function(x) {
 print(x)
}

###

# almost identical simple function
funfails <- function(thisx) {
 print(thisx)
}

###

funworks(fit1)
funfails(fit1)

###

The explanation as I understand it...

print called on this object gets passed to print.mixfitEM(), which is:


function (x, digits = getOption("digits"), ...)
{
 family <- x$family
 mc <- match.call()
 mc$digits <- digits
 fun.name <- paste0("print", family)
 mc[[1]] <- as.name(fun.name)
 eval(mc, environment())
}


Working through the calls, when eval() is called from within funfails(), mc is
printnormal(x = thisx, digits = 7)
and the calling environment does not contain thisx.

In funworks(), it's
printnormal(x = x, digits = 7)

and x is found.

So, I can get around the problem by naming my argument x, as in
funworks(), but that's unsatisfying. Is there something else I can do
to get my functions to work?

And what's the correct way to do what print.mixfitEM() is doing, so
that it works regardless? I poked around for a while, but didn't find
a clear (to me!) answer.

Thanks,
Sarah



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


[R] environments: functions within functions

2023-05-25 Thread Sarah Goslee
Hi,

I ran into a problem with S3 method dispatch and scoping while trying
to use functions from the mixR package within my own functions. I know
enough to find the problem (I think!), but not enough to fix it
myself. The problem isn't really a package-specific problem, so I'm
starting here, and will file an issue with the maintainer once I have
a solution.

Detailed explanation below, but briefly, the S3 methods in this
package use match.call() and then eval() to select the correct
internal method. This works fine from the command line, but if the
method is called from within another function, the use of
environment() within eval() means that the objects passed to the
wrapper function are no longer visible within the eval() call.

I have a two-part question:
A. How do I get around this right now?
B. What would the correct approach be for the package authors?

library(mixR)

# first example from ?mixfit
## fitting the normal mixture models
set.seed(103)
x <- rmixnormal(200, c(0.3, 0.7), c(2, 5), c(1, 1))
data <- bin(x, seq(-1, 8, 0.25))
fit1 <- mixfit(x, ncomp = 2)  # raw data
rm(x, data)
###

# simple function
funworks <- function(x) {
print(x)
}

###

# almost identical simple function
funfails <- function(thisx) {
print(thisx)
}

###

funworks(fit1)
funfails(fit1)

###

The explanation as I understand it...

print called on this object gets passed to print.mixfitEM(), which is:


function (x, digits = getOption("digits"), ...)
{
family <- x$family
mc <- match.call()
mc$digits <- digits
fun.name <- paste0("print", family)
mc[[1]] <- as.name(fun.name)
eval(mc, environment())
}


Working through the calls, when eval() is called from within funfails(), mc is
printnormal(x = thisx, digits = 7)
and the calling environment does not contain thisx.

In funworks(), it's
printnormal(x = x, digits = 7)

and x is found.

So, I can get around the problem by naming my argument x, as in
funworks(), but that's unsatisfying. Is there something else I can do
to get my functions to work?

And what's the correct way to do what print.mixfitEM() is doing, so
that it works regardless? I poked around for a while, but didn't find
a clear (to me!) answer.

Thanks,
Sarah

-- 
Sarah Goslee (she/her)
http://www.numberwright.com

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


[R] [Rd] R 4.3.1 scheduled for June 16

2023-05-25 Thread Peter Dalgaard via R-help
Full schedule available on developer.r-project.org in a short while.

-- 
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Office: A 4.23
Email: pd@cbs.dk  Priv: pda...@gmail.com

___
r-annou...@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-announce

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


Re: [R] data.frame with a column containing an array

2023-05-25 Thread Georg Kindermann
So is this an expected behavior or is it a bug which should be reported 
somewhere else?

Thanks!
Georg 
 
 

Gesendet: Dienstag, 09. Mai 2023 um 19:28 Uhr
Von: "Bert Gunter" 
An: "Georg Kindermann" 
Cc: "Rui Barradas" , r-help@r-project.org
Betreff: Re: [R] data.frame with a column containing an array

 
 
I think the following may provide a clearer explanation:
 
subs <- c(1,3)
DFA <- data.frame(id = 1:3)
ar <- array(1:12, c(3,2,2))
## yielding
> ar
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12
 
## array subscripting gives
> ar[subs,,]
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    9   12
 
## Now with df's
> DFA[["ar"]] <- ar
>
> DFM <- data.frame(id = 1:3)
> DFM[["M"]] <- matrix(1:6, nc =2)
>
> str(DFM)
'data.frame': 3 obs. of  2 variables:
 $ id: int  1 2 3
 $ M : int [1:3, 1:2] 1 2 3 4 5 6
> str(DFA)
'data.frame': 3 obs. of  2 variables:
 $ id: int  1 2 3
 $ ar: int [1:3, 1:2, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
>
> ## But the data frame print method for these give
> DFM  
  id M.1 M.2
1  1   1   4
2  2   2   5
3  3   3   6
> DFA
  id ar.1 ar.2 ar.3 ar.4
1  1    1    4    7   10
2  2    2    5    8   11
3  3    3    6    9   12
>
> ## [.data.frame subscripting gives
> DFA[subs,]
  id ar
1  1  1
3  3  3
> DFM[subs,]
  id M.1 M.2
1  1   1   4
3  3   3   6
>
> ## but  explicit array subscripting of course works
> DFA$ar[match(subs,DFA$id),,]
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    9   12
 
 
Cheers,
Bert 

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