Craig P. Pyrame
2009-Jun-30 12:00 UTC
[R] Question about creating lists with functions as elements
Dear list, I am trying to construct a list of functions using rep. I can't understand the following: > c(character, character) => list with two functions > rep(character, 2) => error The error says that "object of type 'special' is not subsettable", and I have no idea what this means. Would you please help me. The purpose of doing the above is that I need to use scan for reading files that happen to be too large and a bit irregular for read.table. To make scan work, I need to specify the types of values in each column (record field). I can specify the 'what' argument as follows: > records <- scan(..., what = list(character(0), character(0), integer(0), numeric(0), character(0), ...), ...) but this quickly becomes boring for large enough records. (Why does not scan take a character string with class names, as read.table does, instead of a list with dummy objects?) So I am trying to do tricks, and one idea that seems pretty simple is to create a list of functions that create vectors of a particular type, and apply them (using lapply) to get a list of prototype objects: > types = lapply(c(rep(character, 2), integer, numeric, ...), function(type) type(0)) => error But this fails, as above. Why? Why can c(character, character) create a list of two functions, but rep(character, 2) can't? Another solution to my problem I could find (and you'll hopefully suggest an even better one) is to use class names instead, like so: > types = lapply(c(rep('character', 2), 'integer', 'numeric', ...), function(type) vector(type, 0)) but I am still curious why the above doesn't work as I would expect it to. Best regards, Craig
Henrique Dallazuanna
2009-Jun-30 12:12 UTC
[R] Question about creating lists with functions as elements
>From the help page of rep:"Value: An object of the same type as 'x' (except that 'rep' will coerce pairlists to vector lists)." So, you can do: rep(list(character), 2) On Tue, Jun 30, 2009 at 9:00 AM, Craig P. Pyrame <crappyr@gmail.com> wrote:> Dear list, > > I am trying to construct a list of functions using rep. I can't understand > the following: > > > c(character, character) => list with two functions > > rep(character, 2) => error > > The error says that "object of type 'special' is not subsettable", and I > have no idea what this means. Would you please help me. > > The purpose of doing the above is that I need to use scan for reading files > that happen to be too large and a bit irregular for read.table. To make > scan work, I need to specify the types of values in each column (record > field). I can specify the 'what' argument as follows: > > > records <- scan(..., what = list(character(0), character(0), integer(0), > numeric(0), character(0), ...), ...) > > but this quickly becomes boring for large enough records. (Why does not > scan take a character string with class names, as read.table does, instead > of a list with dummy objects?) So I am trying to do tricks, and one idea > that seems pretty simple is to create a list of functions that create > vectors of a particular type, and apply them (using lapply) to get a list of > prototype objects: > > > types = lapply(c(rep(character, 2), integer, numeric, ...), > function(type) type(0)) => error > > But this fails, as above. Why? Why can c(character, character) create a > list of two functions, but rep(character, 2) can't? > > Another solution to my problem I could find (and you'll hopefully suggest > an even better one) is to use class names instead, like so: > > > types = lapply(c(rep('character', 2), 'integer', 'numeric', ...), > function(type) vector(type, 0)) > > but I am still curious why the above doesn't work as I would expect it to. > > Best regards, > Craig > > ______________________________________________ > R-help@r-project.org mailing list > 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. >-- Henrique Dallazuanna Curitiba-Paraná-Brasil 25° 25' 40" S 49° 16' 22" O [[alternative HTML version deleted]]
Barry Rowlingson
2009-Jun-30 12:20 UTC
[R] Question about creating lists with functions as elements
On Tue, Jun 30, 2009 at 1:00 PM, Craig P. Pyrame<crappyr at gmail.com> wrote:> But this fails, as above. ?Why? ?Why can c(character, character) create a > list of two functions, but rep(character, 2) can't? > > Another solution to my problem I could find (and you'll hopefully suggest an > even better one) is to use class names instead, like so: > >> types = lapply(c(rep('character', 2), 'integer', 'numeric', ...), >> function(type) vector(type, 0)) > > but I am still curious why the above doesn't work as I would expect it to. >I hope this doesn't turn into a debate about expectations vs what actually happens :) I've discovered that rep(list(f),n) might do what you want: > f=function(x){x*2} > l=rep(list(f),5) > l[[1]](4) [1] 8 help(rep) says "It is a generic function" which translates to "you may have some problem finding out exactly what function is called when you do rep(thing)". I don't think there's a method for functions, so it's probably being passed to the generic method which is expecting vectors. It possibly then tries to get an element of f, and fails, a bit like this: > f[1] Error in f[1] : object of type 'closure' is not subsettable - without first checking if the object is a vector (you can do rep(c(1,2),5) you see). Maybe a bug, or a misleading error message, or a documentation problem: check with the latest version of R etc etc etc read the FAQ before submitting a bug etc etc etc. Barry