[R] Read Windows-like .INI files into R data structure?

ngottlieb at marinercapital.com ngottlieb at marinercapital.com
Wed Jun 13 22:51:05 CEST 2007


Earl:

Really depends on the need. XML yes can get crazy (having had to deal
with some
ugly XML).

One can do a correctly formatted XML, that parses via the DOM which does
not mean well formatted XML. It's all 
a matter of design and data structures.

XML advantages: one can define own data types with attributes,
do data validation and nice searching with XPATH which
Is a whole subject in itself.

Sounds like XML is overkill for what you need.

Based on what you indicated, since not an R expert, writing a
Simple C function or Fortran routine would be best way to go,
Also gives you re-usable code if you are processing .ini
Files outside of the R environment.


If you program in Visual Basic or C you can develop a simple
DLL to call the old .ini functions which are document
On MSDN (Microsoft Developers Network). 

However, Looks like the R experts from threads gave a nice solution
using R.

Neil

-----Original Message-----
From: r-help-bounces at stat.math.ethz.ch
[mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Earl F. Glynn
Sent: Wednesday, June 13, 2007 2:57 PM
To: r-help at stat.math.ethz.ch
Subject: Re: [R] Read Windows-like .INI files into R data structure?

<ngottlieb at marinercapital.com> wrote in message
news:<0946E293C7C22A45A0E33BA14FAA8D88F38818 at 500MAIL.goldbox.com>...
> .Ini files are, for lack of a better description, ancient.

In this case a device is creating the INI files as part of an
experiment, so 
the file format cannot be changed (at least easily).

I've looked at XML files from time to time and I'm amazed more don't 
complain how bloated, if not wasteful, they are.  I've seen XML files
that 
were megabytes long when they held kilobytes worth of data.  INI files
may 
be ancient, but they can be efficient and effective compared with XML.
In 
some cases, "newer" may not really be better (but "newer" may have the 
"momentum" behind it).


"Gabor Grothendieck" <ggrothendieck at gmail.com> wrote in message 
news:<971536df0706121623p14725cbbp82610f2d3149a9e7 at mail.gmail.com>...
> In thinking about this a bit more here is an even shorter solution
where
> Lines.raw is as before:
>
> # Lines <- readLines("myfile.ini")
> Lines <- readLines(textConnection(Lines.raw))
> Lines2 <- chartr("[]", "==", Lines)
> DF <- read.table(textConnection(Lines2), as.is = TRUE, sep = "=", fill
= 
> TRUE)
> L <- DF$V1 == ""
> subset(transform(DF, V3 = V2[which(L)[cumsum(L)]])[1:3], V1 != "")

Thanks for your helpful suggestions, Gabor.  Perhaps your "zoo" option
is 
more elegant, but I try to use as few packages as possible, so this
option 
seemed the best for me.

Since in my problem the structure of the INI sections is almost static
and 
always present, I extended your example to create an in-memory list of 
everything in the INI file with this function:

# Prototype of how to read INI files to process olfactometer data
# efg, 13 June 2007
# Thanks to Gabor Grothendieck for helpful suggestions in the R-Help
# mailing list on how to parse the INI file.
Parse.INI <- function(INI.filename)
{
  connection <- file(INI.filename)
  Lines  <- readLines(connection)
  close(connection)

  Lines <- chartr("[]", "==", Lines)  # change section headers

  connection <- textConnection(Lines)
  d <- read.table(connection, as.is = TRUE, sep = "=", fill = TRUE)
  close(connection)

  L <- d$V1 == ""                    # location of section breaks
  d <- subset(transform(d, V3 = V2[which(L)[cumsum(L)]])[1:3],
                           V1 != "")

  ToParse  <- paste("INI.list$", d$V3, "$",  d$V1, " <- '",
                    d$V2, "'", sep="")

  INI.list <- list()
  eval(parse(text=ToParse))

  return(INI.list)
}


Here's an example of using the above function (I'll put the sample input

file below):

INI1 <- Parse.INI("sample.ini")

# Explore INI contents
summary(INI1)

INI1$SystemSetup$OlfactometerCode
INI1$DefaultLevels
unlist(INI1$DefaultLevels)
INI1$Map

INI1$Map$port1
as.integer( unlist( strsplit(INI1$Map$port1, ",") ) )

= = = = =
Sample output:

> INI1 <- Parse.INI("sample.ini")
>
> # Explore INI contents
> summary(INI1)
              Length Class  Mode
SystemSetup   1      -none- list
Files         8      -none- list
DefaultLevels 4      -none- list
OdorNames     2      -none- list
Map           3      -none- list
>
> INI1$SystemSetup$OlfactometerCode
[1] "3"
> INI1$DefaultLevels
$FC00
[1] "50"

$FC01
[1] "100"

$FC02
[1] "50"

$FC10
[1] "50"

> unlist(INI1$DefaultLevels)
 FC00  FC01  FC02  FC10
 "50" "100"  "50"  "50"
> INI1$Map
$port0
[1] "0,0,0,0,0,0,0,0,0,0,0,0"

$port1
[1] "0,0,0,0,0,0,0,0,0,0,0,0"

$port2
[1] "0,0,0,0,0,0,0,0,0,0,0,0"

>
> INI1$Map$port1
[1] "0,0,0,0,0,0,0,0,0,0,0,0"
> as.integer( unlist( strsplit(INI1$Map$port1, ",") ) )
 [1] 0 0 0 0 0 0 0 0 0 0 0 0

= = = = =
Sample input file, sample.ini:

[SystemSetup]
OlfactometerCode=3
[Files]
prelog0=Part0.txt
date0=2:06:27.461 PM 6/9/2007
note0=group1-1
name0=group1
prelog1=Part1.txt
date1=2:09:16.809 PM 6/9/2007
note1=group1-1
name1=group1-1
[DefaultLevels]
FC00=50
FC01=100
FC02=50
FC10=50
[OdorNames]
port0=None
port1=None
[Map]
port0=0,0,0,0,0,0,0,0,0,0,0,0
port1=0,0,0,0,0,0,0,0,0,0,0,0
port2=0,0,0,0,0,0,0,0,0,0,0,0

= = = = =

Thanks again, Gabor!

efg

Earl F. Glynn
Scientific Programmer
Stowers Institute for Medical Research

______________________________________________
R-help at 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
and provide commented, minimal, self-contained, reproducible code.
--------------------------------------------------------

 
 
This information is being sent at the recipient's request or...{{dropped}}



More information about the R-help mailing list