2014-03-27 77 views
1

我有一個長文件,其中存儲了不同參數的值。這裏是數據的非常簡單的例子。有以上幾行C5。我想查找ISVEGISDISP的值。我發現MATLAB命令找到ISVEG的價值,但我不能改變,要R code使用R查找值的文本挖掘

C5 MOMENTUM ADVEC AND HORIZ DIFF SWITCHES AND MISC SWITCHES 
* 
* 
C5 ISCDMA ISAHMF ISDISP ISWASP ISDRY ISQQ ISRLID ISVEG ISVEGL ISITB ISEVER IINTPG 
      0  1  0  0  -99  1  0  0  0  0  0  0 
C6 Testing 
* 
* 
C6 par1 par2 
    10  12 

Matlab代碼:

% inpfile is the file where the above sample data is stored 
fid=fopen(inpfile,'r'); 
%C5 
linestr = getstring(fid,'C5'); 
linestr = getstring(fid,'C5'); 
linestr = fgets(fid); 
val = str2num(linestr); 
isveg = val(8); 

我認爲,我們可以使用readLines但我看完後卡住線。我使用正則表達式嗎?

sampledata <- readLines("sampledata.txt") 

dput(的sampleData)加入

dput(sampledata) 
c(" C5 MOMENTUM ADVEC AND HORIZ DIFF SWITCHES AND MISC SWITCHES", 
" *", " *", " C5 ISCDMA ISAHMF ISDISP ISWASP ISDRY ISQQ ISRLID ISVEG ISVEGL ISITB ISEVER IINTPG", 
"    0  1  0  0  -99  1  0  0  0  0  0  0", 
" C6 Testing", " * ", " *", " C6 par1 par2 ", "   10  12" 
) 
+0

是否有任何形式的組織/格式的文件中的文本?意思是說,它可以被放入某種結構化的形式嗎?這看起來不像你的樣品。 –

+0

@RichardScriven我猜數據不是結構化的。 –

回答

0

這是我想出了。我想知道是否有一個簡單的解決方案。

> sampledata <- readLines("C:/Users/jdbaba/sampledata.txt") 
Warning message: 
In readLines("C:/Users/jdbaba/sampledata.txt") : 
    incomplete final line found on 'C:/Users/jdbaba/sampledata.txt' 
> linestr <- grep(pattern="C5", sampledata) 
> linestr 
[1] 1 4 

# Since I am interested to read values one line below C5 I used linestr[2]+1 
> sampledata[linestr[2]+1] 
[1] "    0  1  0  0  -99  1  0  0  0  0  0  0" 
> temp <- read.table(text=sampledata[linestr[2]+1], sep="") 
> temp 
    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
1 0 1 0 0 -99 1 0 0 0 0 0 0 
> isveg <- as.numeric(temp[8]) 
> isveg 
[1] 0 
1

這是我想出來的。由於您試圖獲得的值都爲零,並且還有其他零,因此我將要查找的值切換爲10和5,並將相同格式的另一行(C7)添加爲值20和8(用於ISDISP和ISVEG)。 這裏有一個函數,它可能在整個文件中工作(假設格式是所有感興趣的線)。


這裏的文字:

text <- "C5 MOMENTUM ADVEC AND HORIZ DIFF SWITCHES AND MISC SWITCHES 
* 
* 
C5 ISCDMA ISAHMF ISDISP ISWASP ISDRY ISQQ ISRLID ISVEG ISVEGL ISITB ISEVER IINTPG 
      0  1  10  0  -99  1  0  5  0  0  0  0 
C6 Testing 
* 
* 
C6 par1 par2 
10  12 
** 
C7 ISCDMA ISAHMF ISDISP ISWASP ISDRY ISQQ ISRLID ISVEG ISVEGL ISITB ISEVER IINTPG 
      0  1  20  0  -99  1  0  8  0  0  0  0" 

這裏的功能,這需要一個單列data.frameread.csv作爲參數讀取。

valueFinder <- 
    function(xx) 
    { 
    xx[, 1] <- as.character(xx[, 1]) 
    index <- which(sapply(1:nrow(xx), function(i) grep("(ISDISP|ISVEG)", xx[i, ])) == TRUE) 
    aa <- lapply(index, function(j) unlist(strsplit(xx[j, ], " "))) 
    ss <- lapply(index, function(z) unlist(strsplit(xx[z+1, ], "[[:space:]]+"))) 
    d <- as.data.frame(do.call(rbind, lapply(1:length(ss), function(w){ 
     ss[[w]][aa[[w]][nzchar(aa[[w]])] == "ISDISP" | aa[[w]][nzchar(aa[[w]])] == "ISVEG"] 
     }))) 
    rownames(d) <- sapply(aa, function(x) x[1]) 
    colnames(d) <- c("ISDISP", "ISVEG") 
    return(d) 
    } 

而這裏的結果,顯示他們來自的價值觀和哪一行。

> xx <- read.csv(text = text, header = FALSE) 
> valueFinder(xx) 
## ISDISP ISVEG 
## C5  10  5 
## C7  20  8 
+0

非常感謝您的努力。有用。 –

+0

沒問題。很高興它適合你。 –

+0

這絕對可以變成一個功能,以在更大的文本文件上操作。 –

1

您可以簡單地使用read.csv(..., sep='')至少如果感興趣的文本是第一行。 (如果沒有,添加一些代碼砍感興趣的線路) 這讓你與你的興趣領域一個數據幀:

> txt <- read.csv('so.csv', sep='') 

> txt 
    C5 ISCDMA ISAHMF ISDISP ISWASP ISDRY ISQQ ISRLID ISVEG ISVEGL ISITB ISEVER IINTPG 
1 0  1  0  0 -99  1 0  0  0  0  0  0  NA 

> txt$ISVEG 
[1] 0 
> txt$ISDISP 
[1] 0 

> str(txt) 
'data.frame': 1 obs. of 13 variables: 
$ C5 : int 0 
$ ISCDMA: int 1 
$ ISAHMF: int 0 
$ ISDISP: int 0 
$ ISWASP: int -99 
$ ISDRY : int 1 
$ ISQQ : int 0 
$ ISRLID: int 0 
$ ISVEG : int 0 
$ ISVEGL: int 0 
$ ISITB : int 0 
$ ISEVER: int 0 
$ IINTPG: logi NA 
+0

謝謝你的努力。在我的真實文本中,C5之前有很多行,所以我需要額外的一段代碼來使用這種方式。 –

+0

然後,您只需要一行或兩個額外的內容即可剪切並呈現感興趣的行。文字處理並不像你發現的那樣是R的力量 - 我確信有一些非直覺名字的重要功能。我現在很忙,但我會稍後再看。 – smci