2014-01-11 41 views

回答

1

下面是給予了確切的same question R上的幫助,2007年(感謝@Spacedman指出了這一點)答案:

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) 
} 

其實,我寫了一個短,大概車功能(即並非涵蓋所有角落的情況下),這對我來說現在的工作:

read.ini <- function(x) { 
    if(length(x)==1 && !any(grepl("\\n", x))) lines <- readLines(x) else lines <- x 
    lines <- strsplit(lines, "\n", fixed=TRUE)[[1]] 
    lines <- lines[!grepl("^;", lines) & nchar(lines) >= 2] # strip comments & blank lines 
    lines <- gsub("\\r$", "", lines) 
    idx <- which(grepl("^\\[.+\\]$", lines)) 
    if(idx[[1]] != 1) stop("invalid INI file. Must start with a section.") 

    res <- list() 
    fun <- function(from, to) { 
     tups <- strsplit(lines[(from+1):(to-1)], "[ ]*=[ ]*") 
     for (i in 1:length(tups)) 
      if(length(tups[[i]])>2) tups[[i]] <- c(tups[[i]][[1]], gsub("\\=", "=", paste(tail(tups[[i]],-1), collapse="="))) 
     tups <- unlist(tups) 
     keys <- strcap(tups[seq(from=1, by=2, length.out=length(tups)/2)]) 
     vals <- tups[seq(from=2, by=2, length.out=length(tups)/2)] 
     sec <- strcap(substring(lines[[from]], 2, nchar(lines[[from]])-1)) 
     res[[sec]] <<- setNames(vals, keys) 
    } 
    mapply(fun, idx, c(tail(idx, -1), length(lines)+1)) 
    return(res) 
} 

其中strcap是一個輔助功能是大寫的字符串:

strcap <- function(s) paste(toupper(substr(s,1,1)), tolower(substring(s,2)), sep="") 

也有一些C解決方案,如inihlibini可能有用。雖然我沒有嘗試過。

+0

我建議您使用內部'fun'函數的'return'參數來代替使用全球分配。現在你的代碼是'for'循環和'apply'循環之間的一個混合體。 –

+0

使用'return'時,如何在結果中設置條目的名稱?我的意思是如何在上面的代碼中返回'sec'的值? –