[R] Access and assign list sub-elements using a string such as l$a$b

2006-06-15 Thread Gregory Jefferis
If I have a list I can set a sub-element as follows on the command line:

people=list()
people$tom$hair=brown
people

But what if I have a string containing the name of the sub-element that I
want to access?

subel= people$tom$hair

get(subel) # returns error
assign(subel,red) # silent but doesn't change list
people

The attempts above using assign/get won't do what I am trying to do [nor
according to the help should they].  I would be very grateful for any
suggestions.  Many thanks,

Greg.

-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
University of Cambridge Cambridge
Downing Street  CB2 1TP
Cambridge, CB2 3EJ 
United Kingdom

Lab Tel: +44 (0)1223 336683 Office: +44 (0)1223 339899
Lab Fax: +44 (0)1223 336676

http://www.zoo.cam.ac.uk/zoostaff/jefferis.html   [EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


[R] Interpolate univariate data on regular 3D grid to new 3D grid

2006-03-14 Thread Gregory Jefferis
Dear R Users,

I have some data that is very similar in form to a 3D image - ie univariate
data on a regular 3D grid.  I keep this as a 3D numeric array in R with
attributes describing the sampling points along the 3 dimensions.

I would like to interpolate this onto a new regular 3D grid that I specify
(eg by supplying 3 vectors corresponding to the new grid locations on each
of the 3 dimensions).  Interpolation methods would ideally include nearest
neighbour and linear.

The arrays can be large ( 1e7 points) so I would like this to be efficient.
I can find lots of 1d or 2d interpolation methods but no 3d ones and
anything that I write will probably take me a while to optimise.

Many thanks for any suggestions,

Greg Jefferis.
-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
University of Cambridge Cambridge
Downing Street  CB2 1TP
Cambridge, CB2 3EJ 
United Kingdom

Lab Tel: +44 (0)1223 336683 Office: +44 (0)1223 339899
Lab Fax: +44 (0)1223 336676

http://www.zoo.cam.ac.uk/zoostaff/jefferis.html   [EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


[R] Correct way to test for exact dimensions of matrix or array

2006-01-10 Thread Gregory Jefferis
Dear R Users,

I want to test the dimensions of an incoming vector, matrix or array safely
and succinctly.  Specifically I want to check if the unknown object has
exactly 2 dimensions with a specified number of rows and columns.

I thought that the following would work:

 obj=matrix(1,nrow=3,ncol=5)
 identical( dim( obj) , c(3,5) )
[1] FALSE  

But it doesn't because c(3,5) is numeric and the dims are integer.  I
therefore ended up doing something like:

 identical( dim( obj) , as.integer(c(3,5)))

OR

 isTRUE(all( dim( obj) == c(3,5) ))

Neither of which feel quite right.  Is there a 'correct' way to do this?

Many thanks,

Greg Jefferis.

PS Thinking about it, the second form is (doubly) wrong because:

 obj=array(1,dim=c(3,5,3,5))
 isTRUE(all( dim( obj) == c(3,5) ))
[1] TRUE

OR 
 obj=numeric(10)
 isTRUE(all( dim( obj) == c(3,5) ))
[1] TRUE

(neither of which are equalities that I am happy with!)

-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
University of Cambridge Cambridge
Downing Street  CB2 1TP
Cambridge, CB2 3EJ 
United Kingdom

Tel: +44 (0)1223 336683 +44 (0)1223 339899
Fax: +44 (0)1223 336676 +44 (0)1223 337720

[EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] Correct way to test for exact dimensions of matrix or array

2006-01-10 Thread Gregory Jefferis
Thanks for suggestions.  This is a simple question in principle, but there
seem to be some wrinkles - I am always having to think quite carefully about
how to test for equality in R.  I should also have said that I would like
the check to be efficient as well safe and succinct.

One suggestion was:

isTRUE(all.equal(dim(obj), c(3, 5)))

But that is not so efficient because all.equal does lots of work esp if it
the objects are not equal.

Another suggestion was:

all( dim( obj) == c(3,5) )

But that is not safe eg because dim(vector(10)) is NULL and
all(NULL==c(3,5)) is actually TRUE (to my initial surprise) so vectors would
pass through the net.

So, so far the only way that is efficient, safe and succinct is:

identical( dim( obj) , as.integer(c(3,5)))

Martin Maechler pointed out that at the beginning of a function you might
want to break down the test into something less succinct, that printed more
specific error messages - a good suggestion for a top level function that is
supposed to be user friendly.

Any other suggestions?  Many thanks,

Greg Jefferis.

On 10/1/06 15:13, Martin Maechler [EMAIL PROTECTED] wrote:

 Gregory == Gregory Jefferis [EMAIL PROTECTED]
 on Tue, 10 Jan 2006 14:47:43 + writes:
 
 Gregory Dear R Users,
 
  Gregory I want to test the dimensions of an incoming
  Gregory vector, matrix or array safely
 
 
 Gregory and succinctly.  Specifically I want to check if
 Gregory the unknown object has exactly 2 dimensions with a
 Gregory specified number of rows and columns.
 
 Gregory I thought that the following would work:
 
 obj=matrix(1,nrow=3,ncol=5)
 identical( dim( obj) , c(3,5) )
 Gregory [1] FALSE
 
 Gregory But it doesn't because c(3,5) is numeric and the dims are
 integer.  I
 Gregory therefore ended up doing something like:
 
 identical( dim( obj) , as.integer(c(3,5)))
 
 Gregory OR
 
 isTRUE(all( dim( obj) == c(3,5) ))
 
 the last one is almost perfect if you leave a way the superfluous
 isTRUE(..).
 
 But, you say that it's part of your function checking it's
 arguments.
 In that case, I'd recommend
 
  if(length(d - dim(obj)) != 2)
   stop('d' must be matrix-like)
  if(!all(d == c(3,5)))
   stop(the matrix must be  3 x 5)
 
 which also provides for nice error messages in case of error.
 A more concise form with less nice error messages is
 
   stopifnot(length(d - dim(obj)) == 2,
 d == c(3,50))
 
   ## you can leave away  all(.)  for things in stopifnot(.)
 
 
 
 
 Gregory Neither of which feel quite right.  Is there a 'correct' way to
 do this?
 
 Gregory Many thanks,
 
 You're welcome,
 Martin Maechler, ETH Zurich
 
 Gregory Greg Jefferis.
 
 Gregory PS Thinking about it, the second form is (doubly) wrong because:
 
 obj=array(1,dim=c(3,5,3,5))
 isTRUE(all( dim( obj) == c(3,5) ))
 Gregory [1] TRUE
 
 Gregory OR 
 obj=numeric(10)
 isTRUE(all( dim( obj) == c(3,5) ))
 Gregory [1] TRUE
 
 Gregory (neither of which are equalities that I am happy with!)
 

-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
University of Cambridge Cambridge
Downing Street  CB2 1TP
Cambridge, CB2 3EJ 
United Kingdom

Tel: +44 (0)1223 336683 +44 (0)1223 339899
Fax: +44 (0)1223 336676 +44 (0)1223 337720

[EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


[R] 3D density estimation with library sm - no estimate returned

2005-05-27 Thread Gregory Jefferis
Dear List,

I have been trying to use library sm to do density estimation on a 3D
dataset.  I am using the current MacOS X binary of sm from CRAN.  If I do
this on a 2D dataset, sm.density returns a list including the component
estimate which contains the density estimate over a uniform grid.  When
doing this with 3D data, although I get a nice plot (even when I don't ask
for one), the returned list only contains the original data (see below).  It
would appear that the internal function sm.density.3d is returning NULL.
Have I misunderstood what should be returned?  Is this a platform specific
problem?  Can someone suggest a fix or an alternative library for my
application?  Very many thanks for your help,

Greg Jefferis.

 R.version
 _ 
platform powerpc-apple-darwin7.9.0
arch powerpc   
os   darwin7.9.0
system   powerpc, darwin7.9.0
status   Patched   
major2 
minor1.0   
year 2005  
month05
day  12
language R

 library(sm)
 str(sm.density(matrix(rnorm(300),ncol=3),display=none))
List of 2
 $ data:List of 3
  ..$ x: num [1:100, 1:3]  0.9470 -1.5112  1.0589 -0.0884 -0.1900 ...
  .. ..- attr(*, dimnames)=List of 2
  .. .. ..$ : NULL
  .. .. ..$ : chr [1:3]   
  ..$ nbins: num 0
  ..$ freq : num [1:100] 1 1 1 1 1 1 1 1 1 1 ...
 $ call: language sm.density(x = matrix(rnorm(300), ncol = 3), display =
none)
 str(sm.density(matrix(rnorm(200),ncol=2),display=none))
List of 10
 $ eval.points: num [1:50, 1:2] -2.67 -2.57 -2.47 -2.38 -2.28 ...
  ..- attr(*, dimnames)=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] xnew ynew
 $ estimate   : num [1:50, 1:50] 3.76e-05 5.10e-05 7.57e-05 1.22e-04
2.05e-04 ...
 $ h  : Named num [1:2] 0.414 0.512
  ..- attr(*, names)= chr [1:2]  
 $ h.weights  : num [1:100] 1 1 1 1 1 1 1 1 1 1 ...
 $ weights: num [1:100] 1 1 1 1 1 1 1 1 1 1 ...
 $ se : num [1:50, 1:50] 0.0306 0.0306 0.0306 0.0306 0.0306 ...
 $ upper  : num [1:50, 1:50] 0.00454 0.00468 0.00489 0.00523 0.00571 ...
 $ lower  : num [1:50, 1:50] 0 0 0 0 0 0 0 0 0 0 ...
 $ data   :List of 3
  ..$ x: num [1:100, 1:2] -0.694 -0.192  0.149 -0.718 -0.357 ...
  .. ..- attr(*, dimnames)=List of 2
  .. .. ..$ : NULL
  .. .. ..$ : chr [1:2]  
  ..$ nbins: num 0
  ..$ freq : num [1:100] 1 1 1 1 1 1 1 1 1 1 ...
 $ call   : language sm.density(x = matrix(rnorm(200), ncol = 2),
display = none)
 



-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
Downing Street  Cambridge
Cambridge, CB2 3EJ  CB2 1TP

Tel: +44 (0)1223 336683 +44 (0)1223 339899
Fax: +44 (0)1223 336676 +44 (0)1223 337720

[EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] Reverse plot axes with xlim=rev(range(x)) fails with asp=1

2005-03-07 Thread Gregory Jefferis
Dear Roger,

Thank you for your suggestion and explanation, that was v. helpful.  I also
found the axTicks() command to help generate the normal sequences for tick
marks and labels used in your 'kludge' eg:

plot(y=-y,x=x, ylim=range(-y), asp=1, axes=FALSE)
box()
axis(1) 
axis(2, at=axTicks(2), label=axTicks(2)*-1)

Many thanks,

Greg.


On 5/3/05 7:19 pm, Roger Bivand [EMAIL PROTECTED] wrote:

 On Sat, 5 Mar 2005, Gregory Jefferis wrote:
 
 Dear R users,
 
 I would like to reverse the axes on some xy plots (for example to set the
 origin at the top left rather than the bottom left).  I had planned to use
 something of the following form:
 
 plot(y=y-c(20,4,5,6),x=x-c(10,20,30,40),ylim=rev(range(y)))
 
 ie reversing ylim to reverse the y axis.  This works fine however I also
 want to use the parameter asp=1 to ensure that equal distances in the x or y
 direction are plotted as such on the screen.  However the simple example I
 showed above now fails:
 
 plot(y=y-c(20,4,5,6),x=x-c(10,20,30,40),ylim=rev(range(y)),asp=1)
 
 The actual ylim used is considerably less than it should be, so no points
 appear on the plot.
 
 Can anyone suggest a simple remedy?
 
 plot(y=-y,x=x, ylim=range(-y), asp=1, axes=FALSE)
 box()
 axis(1)
 axis(2, at=seq(-20,-5,5), label=seq(20,5,-5))
 
 is a simple kludge, the explanation is touched on in a comment in
 src/main/plot.c, after line 564:
 
  * The use of asp can have weird effects when axis is an
  * interpreted function.  It has to be internal so that the
  * full computation is captured in the display list.
 
 and may be related to the sign of ydelta being dropped in line 652 (for
 the y axis) and Gscale() being possibly called in line 666 with incorrect
 assumptions about whether to add or subtract the correction factor -
 untried!
 
 
 Many thanks,
 
 Greg Jefferis.
 
 PS I would guess that the origin of this behaviour is that plot.window
 expects xlim (and ylim) to be in the order xmin,xmax (or ymin,ymax) when it
 sets about redefining xlim and ylim if asp!=NA.  If that suggestion is
 correct, I'm not quite sure why the restriction is necessary.
 
 

-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
Downing Street  Cambridge
Cambridge, CB2 3EJ  CB2 1TP

Tel: +44 (0)1223 336683 +44 (0)1223 339899
Fax: +44 (0)1223 336676 +44 (0)1223 337720

[EMAIL PROTECTED]

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


[R] Reverse plot axes with xlim=rev(range(x)) fails with asp=1

2005-03-05 Thread Gregory Jefferis
Dear R users,

I would like to reverse the axes on some xy plots (for example to set the
origin at the top left rather than the bottom left).  I had planned to use
something of the following form:

plot(y=y-c(20,4,5,6),x=x-c(10,20,30,40),ylim=rev(range(y)))

ie reversing ylim to reverse the y axis.  This works fine however I also
want to use the parameter asp=1 to ensure that equal distances in the x or y
direction are plotted as such on the screen.  However the simple example I
showed above now fails:

 plot(y=y-c(20,4,5,6),x=x-c(10,20,30,40),ylim=rev(range(y)),asp=1)

The actual ylim used is considerably less than it should be, so no points
appear on the plot.

Can anyone suggest a simple remedy?

Many thanks,

Greg Jefferis.

PS I would guess that the origin of this behaviour is that plot.window
expects xlim (and ylim) to be in the order xmin,xmax (or ymin,ymax) when it
sets about redefining xlim and ylim if asp!=NA.  If that suggestion is
correct, I'm not quite sure why the restriction is necessary.

-- 
Gregory Jefferis, PhD   and:
Research Fellow
Department of Zoology   St John's College
Downing Street  Cambridge
Cambridge, CB2 3EJ  CB2 1TP

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


[R] Data frame from list of lists

2003-09-22 Thread Gregory Jefferis
This seems to be a simple problem, and I feel that there ought to be a
simple answer, but I can't seem to find it.

I have a function that returns a number of values as a heterogeneous list -
always the same length and same names(), but a number of different data
types, including character.  I want to apply it to many inputs, resulting in
a list of lists.

I would like to turn this list of lists into a single data frame in which
each row corresponds to one of the original sublists.

Here is a toy example:

myfunc=function(x) return(list(A=x,L=letters[x],T=Sys.time()))
ListOfLists=lapply(1:4,myfunc)
ListOfDataFrames=lapply(ListOfLists,as.data.frame)
df=do.call(rbind,ListOfDataFrames)

df

Which gives:

   A L   T
1  1 a 2003-09-22 02:08:44
11 2 b 2003-09-22 02:08:44
12 3 c 2003-09-22 02:08:44
13 4 d 2003-09-22 02:08:44

Which is what I want (bar the rownames).  The problem is that this can be
very slow, particularly the last rbind step, when I have a large data set
(e.g. 5000 rows x20 cols).

I thought that one improvement might be to preassign the data frame since I
know how big it should be and then make assignments row by row.  But it
turns out that I can't then assign rows to the data frame one at a time - I
get errors because factor levels don't exist e.g.:

df[5:10,]=df[4,] 
for (i in 5:10){   
df[i,]=as.data.frame(myfunc(i))
}

I presume that rbind.data.frame normally looks after adding extra levels to
factors as they appear in the new rows being appended to the data frame. If
anyone has a solution that is quick (and/or elegant), I would be extremely
grateful,

Greg Jefferis.

__
Greg Jefferis,  Lab Address: Liqun Luo, Herrin 144
Neurosciences PhD Programme e-mail: [EMAIL PROTECTED]
Dept Biological Sciences,   Lab: (650) 725 5809
Gilbert Biology Building,   Fax: (650) 723 0589
371 Serra Mall,
Stanford, CA 94305-5020.   Home: (650) 326 9597

__
[EMAIL PROTECTED] mailing list
https://www.stat.math.ethz.ch/mailman/listinfo/r-help


Re: [R] Data frame from list of lists (Quick Summary)

2003-09-22 Thread Gregory Jefferis
Here is a quick summary, since I always like it when people post the useful
answers they get (thanks very much to the three respondents).  What I learnt
was (and apologies to those list members for whom these are not exactly
revelations):

1) When making dataframes, work column-wise not row-wise when possible.
This is likely to be much faster (e.g. cbind not rbind) and friendlier
(data.frame(ListOfColumns) is a one liner, whereas data.frame(ListOfRows)
doesn't work).

2) To prevent complex classes like POSIXct (a date) from being unclassed:
do.call(c,lapply(list,FUN)) is better than sapply(list,FUN)

Code:
#
# The input data was:
myfunc=function(x) return(list(A=x,L=letters[x],T=Sys.time()))
ToyListOfLists=lapply(1:4,myfunc)

# My Solution was:
#
FirstSubList=ToyListOfLists[[1]]
getCol=function(n) do.call( c,lapply(ToyListOfLists,function(x) x[[n]]) )
ListOfCols=lapply(seq(FirstSubList),getCol)
df=data.frame(ListOfCols)
names(df)=names(FirstSubList)

# Damon Wischik's solution
# this is essentially the same but better, since:
# 1) it will also work if the list returned by myfunc() includes a factor
# 2) the protection against NAs in the list _may_ be useful
#
transpose.list(ToyListOfLists)

transpose.list - function(lst) {
  typicalrow - lst[[1]]
# GJ However, I am not sure that protection against NAs in
# the next 6 lines is necessary
  if (length(lst)1) for (i in 2:length(lst)) {
if (!any(is.na(typicalrow))) break
better - (is.na(typicalrow)  !is.na(lst[[i]]))
for (j in which(better))
  typicalrow[[j]] - lst[[i]][[j]]
  }
  getfield - function(i) {
v - lapply(lst, function(row) row[[i]] )
vv - do.call(c,v)
typicalitem - typicalrow[[i]]
if (is.factor(typicalitem))
  {
  vvf - rep(typicalitem,length(vv))
  codes(vvf) - vv
  vvf
  }
else
  vv
}
  cols - lapply(1:length(typicalrow), function(i) getfield(i))
  names(cols) - names(typicalrow)
# I think the next 2 lines could be replaced by:
# data.frame(cols) 
  df - do.call(data.frame,cols)
  df
}


On 9/22/03 5:44, Liaw, Andy [EMAIL PROTECTED] wrote:

 Don't know if this will be any faster, and it doesn't give you a data frame,
 but the final conversion to data frame is probably fairly easy:
 
 xx - do.call(rbind, lapply(ListOfLists, function(x) do.call(cbind,
 x)))
 xx
A   L   T 
 [1,] 1 a 1064233098
 [2,] 2 b 1064233098
 [3,] 3 c 1064233098
 [4,] 4 d 1064233098
 
 This gives you a character matrix.  The tricky part (for me) is how to get
 that last column back to POSIXct.  I have not dealt with date/time in R
 before.
 
 HTH,
 Andy
 
 
 -Original Message-
 From: Gregory Jefferis [mailto:[EMAIL PROTECTED]
 Sent: Monday, September 22, 2003 5:15 AM
 To: [EMAIL PROTECTED]
 Subject: [R] Data frame from list of lists
 
 
 This seems to be a simple problem, and I feel that there
 ought to be a simple answer, but I can't seem to find it.
 
 I have a function that returns a number of values as a
 heterogeneous list - always the same length and same names(),
 but a number of different data types, including character.  I
 want to apply it to many inputs, resulting in a list of lists.
 
 I would like to turn this list of lists into a single data
 frame in which each row corresponds to one of the original sublists.
 
 Here is a toy example:
 
 myfunc=function(x) return(list(A=x,L=letters[x],T=Sys.time()))
 ListOfLists=lapply(1:4,myfunc)
 ListOfDataFrames=lapply(ListOfLists,as.data.frame)
 df=do.call(rbind,ListOfDataFrames)
 
 df
 
 Which gives:
 
A L   T
 1  1 a 2003-09-22 02:08:44
 11 2 b 2003-09-22 02:08:44
 12 3 c 2003-09-22 02:08:44
 13 4 d 2003-09-22 02:08:44
 
 Which is what I want (bar the rownames).  The problem is that
 this can be very slow, particularly the last rbind step, when
 I have a large data set (e.g. 5000 rows x20 cols).
 
 I thought that one improvement might be to preassign the data
 frame since I know how big it should be and then make
 assignments row by row.  But it turns out that I can't then
 assign rows to the data frame one at a time - I get errors
 because factor levels don't exist e.g.:
 
 df[5:10,]=df[4,]
 for (i in 5:10){
 df[i,]=as.data.frame(myfunc(i))
 }
 
 I presume that rbind.data.frame normally looks after adding
 extra levels to factors as they appear in the new rows being
 appended to the data frame. If anyone has a solution that is
 quick (and/or elegant), I would be extremely grateful,
 
 Greg Jefferis.
 
 __
 
 Greg Jefferis,  Lab Address: Liqun
 Luo, Herrin 144
 Neurosciences PhD Programme e-mail:
 [EMAIL PROTECTED]
 Dept Biological Sciences,   Lab: (650) 725 5809
 Gilbert