[R] Access and assign list sub-elements using a string such as l$a$b
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
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
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
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
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
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
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
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)
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