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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Earl F. Glynn Sent: Wednesday, June 13, 2007 2:57 PM To: [email protected] Subject: Re: [R] Read Windows-like .INI files into R data structure? <[EMAIL PROTECTED]> wrote in message news:<[EMAIL PROTECTED]>... > .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" <[EMAIL PROTECTED]> wrote in message news:<[EMAIL PROTECTED]>... > 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 ______________________________________________ [email protected] 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}} ______________________________________________ [email protected] 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.
