[Rd] Is an R sub-session somehow possible?

2010-09-07 Thread ghostwheel

I wrote the interface between R and TeXmacs. Recently, I added tab
completion. However, there is one slight problem. In order to enable easy
interaction with R, I (I.e. my program) interact with the command-line
interface. This means that the user can invoke demo(), and then R will
interact with the user and ask to press enter.
It also means that the user can enter
a<-c(3,4
and then R will respond with '+'.

The problem is this: the way I implemented tab completion is calling an R
function that creates the completion. But, while in the middle of user
input, I can't call a function.

I guess that ESS for emacs has the same problem. when I enter "a<-c(3,4",
and then on the next line try to do tab completion, ESS replies that 'ESS
process is not ready. Finish your command before trying again'.
Of course while interacting with R on the command line, tab completion does
work.

So, the question is - is there any way to interrupt the current input to R,
call a function, get the return value, and then continue with the input
where it was? To do something similar to what pressing 'tab' in R does
internally? Something like the equivalent of ctrl-Z for a shell?

-- 
View this message in context: 
http://r.789695.n4.nabble.com/Is-an-R-sub-session-somehow-possible-tp2530174p2530174.html
Sent from the R devel mailing list archive at Nabble.com.

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


[Rd] what is the best way for an external interface to interact with graphics, libraries

2010-09-07 Thread ghostwheel

Another message about the R to TeXmacs interface.

1. Graphics
The TeXmacs interface allows the user to directly insert graphics into the
session. 

Since I am not very familiar with programming for R, I implemented the
interaction with graphics in a very primitive way. It was two modes of
working: with X11, and without (for example when working remotely through
ssh without forwarding X11).

In both cases the user has to invoke a command, v(), in order to insert the
current graph into the buffer at the current place.

With X11, the way it works is that when v() is invoked I call recordPlot(),
then open a postscript file, then replayPlot(), and then close the
postscript file and insert it into the session.

Without X11, I open a postscript file ahead of time, then when v() is
called, I close it, and insert it into the session, and then open a new
postscript file.

Obviously quite primitive.I think ideally would be if everything was
transparent to the user - the user does a plot, and the plot is inserted
into the buffer right away, and later, updates to the same plot update the
original plot where it is. But to be able to do that I need to be able to
generate the postscript file of the current plot, and be notified somehow
whenever the plot changes.

Is all that possible? Is there a better way to implement this all?

2. Libraries

A remotely related question is this: the interface with TeXmacs generates
menus that depend on the currently loaded libraries. I'd like to be able to
update the menus whenever a new library is loaded. Is there a possibility to
have a function called whenever this happens? Or would it be advisable to
change the global 'library' function?

-- 
View this message in context: 
http://r.789695.n4.nabble.com/what-is-the-best-way-for-an-external-interface-to-interact-with-graphics-libraries-tp2530208p2530208.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] Is an R sub-session somehow possible?

2010-09-07 Thread ghostwheel


Simon Urbanek wrote:
> 
> 
> On Sep 7, 2010, at 2:06 PM, ghostwheel wrote:
> 
>> a<-c(3,4
>> and then R will respond with '+'.
>> 
>> The problem is this: the way I implemented tab completion is calling an R
>> function that creates the completion. But, while in the middle of user
>> input, I can't call a function.
>> 
> 
> Why not? After the "+" prompt you're back in ReadConsole so it's safe.
> 
> 

I see. ReadConsole() seems quite nice! I should use it.

What about remote sessions? Till now I used ssh, which then opened R. I
guess I could have the user compile and install the program that interfaces
with R on any machine that runs R. Is there another way?

Thanks,
Michael
-- 
View this message in context: 
http://r.789695.n4.nabble.com/Is-an-R-sub-session-somehow-possible-tp2530174p2530233.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] what is the best way for an external interface to interact with graphics, libraries

2010-09-07 Thread ghostwheel


Simon Urbanek wrote:
> 
> 
> I don't know the mechanics of the actual "inserting" in TeXmac but it
> would be trivial to simply create a copy of the plot as EPS (or whatever
> is needed) at the time of insertion. See dev.copy2eps() for a function
> that does exactly that.
> 
> 

Great. It works much better than my recordPlot() hack. But it seems to only
work for 'screen devices'. I'd like to be able to work remotely without X11.
Is there any equivalent graphics device that would be copyable with
dev.copy2eps?  Is there any way to tell R give me whatever you have till now
in eps? 


-- 
View this message in context: 
http://r.789695.n4.nabble.com/what-is-the-best-way-for-an-external-interface-to-interact-with-graphics-libraries-tp2530208p2530256.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] Is an R sub-session somehow possible?

2010-09-07 Thread ghostwheel


Simon Urbanek wrote:
> 
> 
> 
> It doesn't really matter where the R is as long as you have some way of
> getting at the results. You are still leaving us in the dark as of what
> exactly you do (technically) so there is not much detail we can provide...
> 
> 

Sorry, I'll try to provide more detail:

I am trying to provide a good connection between the TeXmacs editor and R.
(A really nice overview of such connections can be found in
http://www.r-project.org/conferences/useR-2004/abstracts/supplements/Urbanek.pdf
;)
What I do is fake a terminal, and interact with the command line interface
to R (something like what the program 'expect' does). To detect that R is
waiting for input I have to check various properties of the terminal. Not
really pretty.
What happens is that:
1. TeXmacs sends me a string to execute. 
2. I pass it to R, and wait for a prompt.
3. I pass all of R's return, somewhat processed back to TeXmacs. Thus, when 
I want to put a graphics inside TeXmacs' buffer, I have to print something
like 'start postscipt graphics', then the postscript file, then 'end
postscript'.

When the user asks for tab completion, TeXmacs sends me a special message
saying that this string needs to be completed. I call a function in R, and
return the result.

My program is able to interact with a remote R session, i.e. the session
will start on a different machine than the one TeXmacs runs on. Luckily, it
is also possible to detect when R waits for a prompt in a remote session by
doing these ugly terminal hacks.

In some cases the R prompt won't be a prompt for another command, but
instead, R is just waiting for user input, or for completion of the previous
input.

Now, my remaining question is this:
When I run R remotely, by emulating a terminal, and interacting with R in
command line mode, AND
when at the same time R is not waiting for a command, but instead for some
other kind of user interaction, my interface can't send to R a request to
execute the code to complete a certain string.
(I.e. call the function t.tab.complete that I attached below).

If I understand correctly, one solution is to write a replacement input
loop, so that R will call my ReadConsole() from time to time, and while I'm
inside that function, I could call R functions to provide tab completion.

In that case, for remote sessions, I would have to compile on the remote
computer this alternative R input loop, and I would have to have one for
every version of R that a user might want to run on the remote machine (the
machine I am currently working with remotely has 11 versions of R
installed...). I was wondering if there is still a way to avoid that, and
interact with the regular input loop, or maybe it is possible to load an
alternative input loop from a package/library inside an already running
regular R interface?
I would like the user to have to do as little as possible in terms of
installing additional programs on a remote machine.

Thanks,
I'm not sure if this was the type of additional information you meant...
Michael

Here is my tab completion routine, ("\2" and "\5" are the codes for TeXmacs
for a start and a stop of blocks. (basically like brackets) ).
-
t.tab.comp<-function(s,curs)
  {
rc.settings(help=F) #This is because of a bug in matchAvailableTopics in
package utils
rc.settings(file=T)

utils:::.assignLinebuffer(substr(s,1,curs))
utils:::.assignEnd(nchar(s))
utils:::.guessTokenFromLine()
utils:::.completeToken()
l=utils:::.retrieveCompletions()
l=sapply(l,function(x) {
  substr(x, nchar(utils:::.CompletionEnv[["token"]])+1,nchar(x) )
} )
i=grep("=$",l)
if( (length(l[-i]) > 10) & (length(i)>0 ) )
l=c(l[i])
s3=utils:::.CompletionEnv[["token"]]
s3=gsub("\"","\"",s3)
deb.l <<- l

cat("\2scheme:(tuple \"",s3,"\"",sep="") ;
cat(" \"")
if( length(l) > 0 )
{
  cat(l,sep="\" \"")
}
else
{
  #cat(s)
  cat("\"\"")
}
cat("\"")
cat(")\5")

   

-- 
View this message in context: 
http://r.789695.n4.nabble.com/Is-an-R-sub-session-somehow-possible-tp2530174p2530527.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] Using 'dimname names' in aperm() and apply()

2012-04-20 Thread ghostwheel
I'm replying here to quite an old thread started by me.

I think the dimnames facility is underused in R.
I'm currently using a 5-dimensional array. It is quite cumbersome to have to
write
y["0"]

Since the array does have dimnames,  I would like to be able to say instead
y[tree="0"]

Below is a function that enables this functionality
--
myslice=function( input.array,...){
  args=list(...)
  if( length(names(args))==0 ) {
d = args
  } else {
d=dimnames( input.array )
for(n in names(args)) {
  i=args[[n]]
  if( is.numeric(i)) {
if( length(d[[n]]) == 0) d[[n]]=i
else d[[n]]=d[[n]][i]
  } else d[[n]]=args[[n]]
}
  }
  dd=dim( input.array )
  for(i in seq(along=dd))
if( length(d[[i]])==0) d[[i]] = seq( dd[i])
  i=sapply(d,length)>1
  new.dimnames=dimnames(input.array)[i]
  d=c(list( input.array ),d)
  ret = do.call("[",d)
  dimnames(ret) = new.dimnames
  ret
}
---
I'm not sure what is the best way to replace "[" for arrays with this
function. I should also implement [<- in the same manner.

One additional feature of this function is that it keeps dimnames.
So, if we have
A=array(1:24,c(2,3,4),dimnames=list(a=c(),b=c(),c=c()))
(btw, why can't I do A=array(1:24,c(a=2,b=3,c=4))?)

Then A[1,,] will give a matrix without dimnames:
--
> A[1,,]
 [,1] [,2] [,3] [,4]
[1,]17   13   19
[2,]39   15   21
[3,]5   11   17   23
--
Whereas the new function keeps the dimnames:
--
> myslice(A,a=1)
  c
b  [,1] [,2] [,3] [,4]
  [1,]17   13   19
  [2,]39   15   21
  [3,]5   11   17   23
--

Another function where using dimnames for MARGIN would be slice.index

Thanks!
Michael

--
View this message in context: 
http://r.789695.n4.nabble.com/Using-dimname-names-in-aperm-and-apply-tp2307013p4574463.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] I wish xlim=c(0, NA) would work. How about I send you a patch?

2012-04-23 Thread ghostwheel
I have also often longed for such a shortcut.

The problem is that most often, my plot statements do not look like this:
plot(y)

but instead like this:
plot( some_very_long_expression_involving(x),
some_other_very_long_expression_involving(x) )

And since I'm working with a GUI, I often go up and change this or that
expression.
Then it starts to be ugly to have to work with
range(pretty(ugly_expressions())). Of course, I could always do
x=some_very_long_expression, y=some_other_very_long_expression; plot(x,y)

Another possible solution would be to use:
plot(x,y, ylim=c(min=9) )
in order to identify which limit I'd like to set. That shouldn't usually
mess up anything, right? 

Michael

--
View this message in context: 
http://r.789695.n4.nabble.com/I-wish-xlim-c-0-NA-would-work-How-about-I-send-you-a-patch-tp4562269p4580388.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] I wish xlim=c(0, NA) would work. How about I send you a patch?

2012-04-26 Thread ghostwheel
The following seems to work well, and I don't think it'll break anything.
The only problem I see is if someone says xlim=c(min=9, max=0), which should
give an error/warning message, but won't.

Michael
---
plot.default=
function (x, y = NULL, type = "p", xlim = NULL, ylim = NULL,
  log = "", main = NULL, sub = NULL, xlab = NULL, ylab = NULL,
  ann = par("ann"), axes = TRUE, frame.plot = axes, panel.first = NULL,
  panel.last = NULL, asp = NA, ...)
  {
localAxis <- function(..., col, bg, pch, cex, lty, lwd) Axis(...)
localBox <- function(..., col, bg, pch, cex, lty, lwd) box(...)
localWindow <- function(..., col, bg, pch, cex, lty, lwd)
plot.window(...)
localTitle <- function(..., col, bg, pch, cex, lty, lwd)
title(...)
xlabel <- if (!missing(x))
  deparse(substitute(x))
ylabel <- if (!missing(y))
  deparse(substitute(y))
xy <- xy.coords(x, y, xlabel, ylabel, log)
xlab <- if (is.null(xlab))
  xy$xlab
else xlab
ylab <- if (is.null(ylab))
  xy$ylab
else ylab
xlim <- if (is.null(xlim))
  range(xy$x[is.finite(xy$x)])
else if( length(xlim)==1 & names(xlim)=="min" ) {
  c(xlim,range(xy$x[is.finite(xy$x)])[2]) }
else if( length(xlim)==1 & names(xlim)=="max" ) {
  c( range(xy$x[is.finite(xy$x)])[1], xlim) }
else xlim
ylim <- if (is.null(ylim))
  range(xy$y[is.finite(xy$y)])
else if( length(ylim)==1 & names(ylim)=="min" ) {
  c( ylim,range(xy$y[is.finite(xy$y)])[2]) }
else if( length(ylim)==1 & names(ylim)=="max" ) {
  c( range(xy$y[is.finite(xy$y)])[1], ylim) }
else ylim
dev.hold()
on.exit(dev.flush())
plot.new()
localWindow(xlim, ylim, log, asp, ...)
panel.first
plot.xy(xy, type, ...)
panel.last
if (axes) {
  localAxis(if (is.null(y))
xy$x
else x, side = 1, ...)
  localAxis(if (is.null(y))
x
else y, side = 2, ...)
}
if (frame.plot)
  localBox(...)
if (ann)
  localTitle(main = main, sub = sub, xlab = xlab, ylab =
ylab,
 ...)
invisible()
  }

--
View this message in context: 
http://r.789695.n4.nabble.com/I-wish-xlim-c-0-NA-would-work-How-about-I-send-you-a-patch-tp4562269p4589316.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] I wish xlim=c(0, NA) would work. How about I send you a patch?

2012-04-26 Thread ghostwheel
Sorry, the previous had a bug and was quite ugly. This is a bit better:
--
function (x, y = NULL, type = "p", xlim = NULL, ylim = NULL,
  log = "", main = NULL, sub = NULL, xlab = NULL, ylab = NULL,
  ann = par("ann"), axes = TRUE, frame.plot = axes, panel.first = NULL,
  panel.last = NULL, asp = NA, ...)
  {
localAxis <- function(..., col, bg, pch, cex, lty, lwd) Axis(...)
localBox <- function(..., col, bg, pch, cex, lty, lwd) box(...)
localWindow <- function(..., col, bg, pch, cex, lty, lwd)
plot.window(...)
localTitle <- function(..., col, bg, pch, cex, lty, lwd)
title(...)
xlabel <- if (!missing(x))
  deparse(substitute(x))
ylabel <- if (!missing(y))
  deparse(substitute(y))
xy <- xy.coords(x, y, xlabel, ylabel, log)
xlab <- if (is.null(xlab))
  xy$xlab
else xlab
ylab <- if (is.null(ylab))
  xy$ylab
else ylab
xlim <- if (is.null(xlim))
  range(xy$x[is.finite(xy$x)])
else if( length(xlim)==1 ) {
  xlim.in=xlim
  xlim = range(xy$x[is.finite(xy$x)])
  xlim[pmatch( names(xlim.in),c("min","max") )] = xlim.in
  xlim
} else xlim
ylim <- if (is.null(ylim))
  range(xy$y[is.finite(xy$y)])
else  if( length(ylim)==1 ) {
  ylim.in=ylim
  ylim = range(xy$y[is.finite(xy$y)])
  ylim[pmatch( names(ylim.in),c("min","max") )] = ylim.in
  ylim
}   else ylim
dev.hold()
on.exit(dev.flush())
plot.new()
localWindow(xlim, ylim, log, asp, ...)
panel.first
plot.xy(xy, type, ...)
panel.last
if (axes) {
  localAxis(if (is.null(y))
xy$x
else x, side = 1, ...)
  localAxis(if (is.null(y))
x
else y, side = 2, ...)
}
if (frame.plot)
  localBox(...)
if (ann)
  localTitle(main = main, sub = sub, xlab = xlab, ylab =
ylab,
 ...)
invisible()
  }
--

--
View this message in context: 
http://r.789695.n4.nabble.com/I-wish-xlim-c-0-NA-would-work-How-about-I-send-you-a-patch-tp4562269p4589400.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] delayedAssign changing values

2012-04-26 Thread ghostwheel
It is really strange that the delayedAssign is evaluated in the environment
it is called from, and thus can have side effects.
so
x=2
y=3
delayedAssign("x", {y <- 7; y+3}) 

gives
> x
[1] 10
> y
[1] 7

Both x and y changed.
More intuitive would have been the behavior
x=2
y=3
delayedAssign("x", local({y <- 7; y+3}) ) 
> x
[1] 10
> y
[1] 3
which only changes x.
Or, at least that should be the default behavior

Michael

--
View this message in context: 
http://r.789695.n4.nabble.com/delayedAssign-changing-values-tp4588108p4590242.html
Sent from the R devel mailing list archive at Nabble.com.

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


Re: [Rd] delayedAssign changing values

2012-04-26 Thread ghostwheel

Simon Urbanek wrote
> 
>> More intuitive would have been the behavior
>> delayedAssign("x", local({y <- 7; y+3}) ) 
>> which only changes x.
> 
> That is questionable - I think it is more logical for both environments to
> be the same as default. Just think if it -- the point here is to access
> lazy evaluation which is exactly what it does - lazy evaluation takes
> place in the original environment, not in another one.
> 

I think I finally understand. My intuition just came from looking at
?delayedAssign.
But delayedAssign came to replace delay(), which "creates a promise to
evaluate the given expression".
When one thinks of delay(), what you said makes sense, you just delay
executing a certain expression in the parent frame.

I think, though, that with the current way it is described and called,
delayedAssign should by default only have the side effect of changing the
variable, i.e. use eval.env=new.env().

The manual states:
This function is invoked for its side effect, which is assigning a promise
to evaluate value to the variable x.

I think that is a nice clear side effect - changing a variable when it is
evaluated...like a delayed "<<-".
Otherwise it seems to me that delayedAssign could cause debugging
nightmares. Luckily, it currently doesn't seem to widely used to cause
them

But you are right that it might be a bit strange that assign.env and
eval.env are different. Maybe that is why there are two different parameters
- to make the side effects clearer?
I tried to find anywhere uses of delayedAssign which make positive use of
side effects other than the assignment, and couldn't find any. Does anyone
know of such a use?

P.S. the end of ?delayedAssign contains this cryptic code:

e <- (function(x, y = 1, z) environment())(1+2, "y", {cat(" HO! "); pi+2})
(le <- as.list(e)) # evaluates the promises

Which I think is another way to create a promise, other than delayedAssign.
But it is really unclear why it sits there at the bottom of the document.
There should probably be more explanation of what this is


--
View this message in context: 
http://r.789695.n4.nabble.com/delayedAssign-changing-values-tp4588108p4591137.html
Sent from the R devel mailing list archive at Nabble.com.

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