using eval-parse-paste in a loop

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

using eval-parse-paste in a loop

Michael Anyadike-Danes
R-helpers

 

I have 120 small Excel sheets to read and I am using
library(xlsReadWrite): one example below.

 

I had hoped to read sheets by looping over a list of numbers in their
name (eg Book1.xls, Book2.xls, etc).

 

I thought I had seen examples which used eval-parse-paste in this way.

 

However, I have not been able to get it to work..

 

1. is this a feasible approach?

 

2. if not advice would be welcome.

 

3. Equally, advice about a better approach would also be v. welcome.

 

I haven't included the data because my failed attempt is
data-independent (and probably more basic).  

 

 

Michael Anyadike-Danes

 

############# show that read.xls works

 

> test <- read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")

> str(test)

'data.frame':   23 obs. of  13 variables:

 $ Off.Flows..Thousands.: num  117.19    NaN     NA   1.43   2.26 ...

 $ Off.Flows..Thousands.: num  8.42 NaN NA 0.08 0.11 0.01 0.11 1.59 0.16
0.04 ...

 $ Off.Flows..Thousands.: num  20 NaN NA 0.2 0.3 0.02 0.32 4.39 0.41
0.11 ...

 $ Off.Flows..Thousands.: num  12.36   NaN    NA  0.14  0.27 ...

 $ Off.Flows..Thousands.: num  7.59 NaN NA 0.11 0.18 0.01 0.14 1.46 0.23
0.06 ...

 $ Off.Flows..Thousands.: num  10.31   NaN    NA  0.12  0.23 ...

 $ Off.Flows..Thousands.: num  7.55 NaN NA 0.08 0.2 0.01 0.11 1.6 0.23
0.05 ...

 $ Off.Flows..Thousands.: num  10.57   NaN    NA  0.19  0.21 ...

 $ Off.Flows..Thousands.: num  9.36 NaN NA 0.13 0.26 0.02 0.13 2.12 0.27
0.07 ...

 $ Off.Flows..Thousands.: num  8.21 NaN NA 0.1 0.19 0.01 0.1 1.9 0.23
0.06 ...

 $ Off.Flows..Thousands.: num  9.04 NaN NA 0.13 0.11 0.01 0.17 1.54 0.17
0.05 ...

 $ Off.Flows..Thousands.: num  13.42   NaN    NA  0.14  0.19 ...

 $ Off.Flows..Thousands.: num  0.37 NaN NA NaN 0.01 NaN 0.01 0.05 0.02
NaN ...

 

############### simple minded attempt substituting eval-parse-paste

 

> nam <- 1

 

> test <-
eval(parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="
numeric")',sep='')))

Error in file(file, "r") : unable to open connection

In addition: Warning message:

In file(file, "r") :

  cannot open file
'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
'Invalid argument'

 

############### stripping off eval, looking for clues

 

>
parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numer
ic")',sep=''))

Error in file(file, "r") : unable to open connection

In addition: Warning message:

In file(file, "r") :

  cannot open file
'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
'Invalid argument'

 

############### stripping off parse, still looking for clues

 

>
paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numeric")',
sep='')

[1] "read.xls(\"Book1.xls\",sheet=1,from=4,colClasses=\"numeric\")"

 

################################



Economic Research Institute of Northern Ireland

Floral Buildings

2-14 East Bridge Street

Belfast BT1 3NQ

Tel:  (028) 90727362

Fax: (028) 90319003




        [[alternative HTML version deleted]]

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: using eval-parse-paste in a loop

Erik Iverson

> ############### stripping off eval, looking for clues
>
>  
>
> parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numer
> ic")',sep=''))
>
> Error in file(file, "r") : unable to open connection
>
> In addition: Warning message:
>
> In file(file, "r") :
>
>   cannot open file
> 'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
> 'Invalid argument'
>

Your clue is that it looks like parseis unsuccessfully trying to open a
file.  Look at ?parse and note the first argument, which you are using
because of positional matching.

You want eval(parse(text = paste(...)))

Best,
Erik Iverson

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: using eval-parse-paste in a loop

Erik Iverson
In reply to this post by Michael Anyadike-Danes
Michael -


>
> 3. Equally, advice about a better approach would also be v. welcome.
>


As an alternative approach, you may want to save the sheet names in a
list and then use the lapply function to read your data into a list.
This would greatly reduce the 'clutter' of objects in your global
environment, and then let you apply analysis functions to each sheet
with subsequent usage of the *apply functions.

Best,
Erik Iverson

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: using eval-parse-paste in a loop

Bert Gunter
In reply to this post by Erik Iverson
As Thomas Lumley has frequently noted, eval(parse...)) should generally be
avoided.

You probably want do.call(), as in

## warning: UNTESTED

lapply(numbs,
function(n)do.call(read.xls,list(file=paste("Book",n,".xls",sep=""),sheet=1,
...)))   ## ... contains the other explicitly names arguments


Note that this would automatically create your list for you.

Cheers,

Bert Gunter
Genentech Nonclinical Statistics

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Erik Iverson
Sent: Tuesday, February 26, 2008 9:29 AM
To: Michael Anyadike-Danes
Cc: [hidden email]
Subject: Re: [R] using eval-parse-paste in a loop


> ############### stripping off eval, looking for clues
>
>  
>
> parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numer
> ic")',sep=''))
>
> Error in file(file, "r") : unable to open connection
>
> In addition: Warning message:
>
> In file(file, "r") :
>
>   cannot open file
> 'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
> 'Invalid argument'
>

Your clue is that it looks like parseis unsuccessfully trying to open a
file.  Look at ?parse and note the first argument, which you are using
because of positional matching.

You want eval(parse(text = paste(...)))

Best,
Erik Iverson

______________________________________________
[hidden email] 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.

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: using eval-parse-paste in a loop

Tony Plate-2
In reply to this post by Michael Anyadike-Danes
Using eval-parse for this looks like overkill.  You should just be able to
do something straightforward like:

for (i in 1:120)
   assign(paste("book", i, sep=""), read.xls(paste("Book", i, ".xls",
sep=""), sheet=1, from=4, colClasses="numeric"))

which would put your spreadsheets in variables book1, book2, etc.

Or, if you want to put everything in a list:

books <- lapply(1:120, function(i) read.xls(paste("Book", i, ".xls",
sep=""), sheet=1, from=4, colClasses="numeric"))

BTW, the reason your attempts with parse() were failing is that default
argument of parse() is a filename (do args(parse) to see this quickly).
You wanted parse(text=...).

-- Tony Plate

Michael Anyadike-Danes wrote:

> R-helpers
>
>  
>
> I have 120 small Excel sheets to read and I am using
> library(xlsReadWrite): one example below.
>
>  
>
> I had hoped to read sheets by looping over a list of numbers in their
> name (eg Book1.xls, Book2.xls, etc).
>
>  
>
> I thought I had seen examples which used eval-parse-paste in this way.
>
>  
>
> However, I have not been able to get it to work..
>
>  
>
> 1. is this a feasible approach?
>
>  
>
> 2. if not advice would be welcome.
>
>  
>
> 3. Equally, advice about a better approach would also be v. welcome.
>
>  
>
> I haven't included the data because my failed attempt is
> data-independent (and probably more basic).  
>
>  
>
>  
>
> Michael Anyadike-Danes
>
>  
>
> ############# show that read.xls works
>
>  
>
>> test <- read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")
>
>> str(test)
>
> 'data.frame':   23 obs. of  13 variables:
>
>  $ Off.Flows..Thousands.: num  117.19    NaN     NA   1.43   2.26 ...
>
>  $ Off.Flows..Thousands.: num  8.42 NaN NA 0.08 0.11 0.01 0.11 1.59 0.16
> 0.04 ...
>
>  $ Off.Flows..Thousands.: num  20 NaN NA 0.2 0.3 0.02 0.32 4.39 0.41
> 0.11 ...
>
>  $ Off.Flows..Thousands.: num  12.36   NaN    NA  0.14  0.27 ...
>
>  $ Off.Flows..Thousands.: num  7.59 NaN NA 0.11 0.18 0.01 0.14 1.46 0.23
> 0.06 ...
>
>  $ Off.Flows..Thousands.: num  10.31   NaN    NA  0.12  0.23 ...
>
>  $ Off.Flows..Thousands.: num  7.55 NaN NA 0.08 0.2 0.01 0.11 1.6 0.23
> 0.05 ...
>
>  $ Off.Flows..Thousands.: num  10.57   NaN    NA  0.19  0.21 ...
>
>  $ Off.Flows..Thousands.: num  9.36 NaN NA 0.13 0.26 0.02 0.13 2.12 0.27
> 0.07 ...
>
>  $ Off.Flows..Thousands.: num  8.21 NaN NA 0.1 0.19 0.01 0.1 1.9 0.23
> 0.06 ...
>
>  $ Off.Flows..Thousands.: num  9.04 NaN NA 0.13 0.11 0.01 0.17 1.54 0.17
> 0.05 ...
>
>  $ Off.Flows..Thousands.: num  13.42   NaN    NA  0.14  0.19 ...
>
>  $ Off.Flows..Thousands.: num  0.37 NaN NA NaN 0.01 NaN 0.01 0.05 0.02
> NaN ...
>
>  
>
> ############### simple minded attempt substituting eval-parse-paste
>
>  
>
>> nam <- 1
>
>  
>
>> test <-
> eval(parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="
> numeric")',sep='')))
>
> Error in file(file, "r") : unable to open connection
>
> In addition: Warning message:
>
> In file(file, "r") :
>
>   cannot open file
> 'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
> 'Invalid argument'
>
>  
>
> ############### stripping off eval, looking for clues
>
>  
>
> parse(paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numer
> ic")',sep=''))
>
> Error in file(file, "r") : unable to open connection
>
> In addition: Warning message:
>
> In file(file, "r") :
>
>   cannot open file
> 'read.xls("Book1.xls",sheet=1,from=4,colClasses="numeric")', reason
> 'Invalid argument'
>
>  
>
> ############### stripping off parse, still looking for clues
>
>  
>
> paste('read.xls("Book',nam,'.xls",sheet=1,from=4,colClasses="numeric")',
> sep='')
>
> [1] "read.xls(\"Book1.xls\",sheet=1,from=4,colClasses=\"numeric\")"
>
>  
>
> ################################
>
>
>
> Economic Research Institute of Northern Ireland
>
> Floral Buildings
>
> 2-14 East Bridge Street
>
> Belfast BT1 3NQ
>
> Tel:  (028) 90727362
>
> Fax: (028) 90319003
>
>
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] 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.
>

______________________________________________
[hidden email] 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.