2014-10-17 43 views
0

這是一個文件的一部分的不同的行提取數據,從一個文件,該文件是從關鍵詞

  GIAO CHEMICAL SHIELDING TENSOR (PPM): 
                  ISOTROPIC 
         X    Y    Z   SHIELDING 
                 ( ANISOTROPY) 

1 C   X 192.9847  -0.3288  0.5647 
      Y  0.8908  133.5254  1.9987 
      Z  -1.5286  1.9986  131.2590 
                  152.5897 
EIGENVALS:  192.9663  130.1130  134.6898 
                 ( 60.5649) 

2 O   X 293.7037  -11.3068  19.4099 
      Y -27.8836  337.6867  -38.0711 
      Z  47.8680  -38.0711  380.8636 
                  337.4180 
EIGENVALS:  283.3105  413.4345  315.5091 
                 ( 114.0247) 

3 H   X  32.4132  -2.6310  -3.6171 
      Y  -0.9732  26.6966  2.2004 
      Z  -1.6244  2.2423  28.7795 
                   29.2964 
EIGENVALS:  34.4129  28.1896  25.2868 
                 (  7.6748) 

4 H   X  32.4132  4.4443  0.5044 
      Y  1.8931  30.1789  0.2675 
      Z  0.0452  0.2257  25.2970 
                   29.2964 
EIGENVALS:  34.4129  28.1895  25.2867 
                 (  7.6748) 

5 H   X  31.3212  -2.3074  3.9610 
      Y  -1.0235  26.9345  -1.8682 
      Z  1.7569  -1.8682  29.0533 
                   29.1030 
EIGENVALS:  33.8408  27.6219  25.8462 
                 (  7.1067) 

6 H   X  32.4086  -3.5167  6.0369 
      Y  -2.5502  27.9731  -8.1180 
      Z  4.3777  -8.1180  37.1798 
                   32.5205 
EIGENVALS:  29.5456  44.7719  23.2441 
                 ( 18.3770) 
..... DONE WITH NMR SHIELDINGS ..... 

我對線之間的數據,「GIAO CHEMICAL屏蔽張量(PPM)」和「.....核磁共振SHIELDINGS DONE .....」

,我要變成一個數據幀,

1C 152.5897 60.5649 
2O 337.4180 114.0247 
3H 29.2964 7.6748 
4H 29.2964 7.6748 
5H 29.1030 7.1067 
6H 32.5205 18.3770 

我有這種性質的其他文件,但我不知道知道從哪裏開始。好的,我可以使用readLines()將文件轉換爲R,但在那之後......?

這裏有一個鏈接到文件,https://drive.google.com/file/d/0B2RulP80ivJaR0NVV1ZLRlpxVDA/view?usp=sharing,而不只是我的刮。一些針對縮短版本的答案不適用於完整文件。

+0

AWKward是你的字 – SriniV 2014-10-17 22:00:56

+1

使用'grepl'來標記你想要的行,'read.fwf'來讀取你想要的列位置。我很確定這個任務已經在SO世界中起作用,因爲我記得沿着這些線路發佈了[r]解決方案。 – 2014-10-17 22:03:27

回答

3

閱讀文件,提取以(可能爲空)序列的空格開始的行,並打開parens後面跟一個數字。然後在第二行中的第3個字符,字符粘貼每個這樣的線58-68和刪除所有空格:

# extract portion of file between ix[1] and ix[2] 
L <- readLines("myfile.dat") 
ix <- grep("GIAO CHEMICAL SHIELDING TENSOR|DONE WITH NMR SHIELDING", L) 
L0 <- L[seq(ix[1]+1, ix[2]-1)] 

# extract fields 
g <- grep("^[ (]*\\d", L0, value = TRUE) 
res <- gsub(" ", "", paste(substr(g, 1, 3), substr(g, 58, 68))) 

這給:

> res 
[1] "1C"  "152.589" "60.564" "2O"  "337.418" "114.024" "3H"  
[8] "29.296" "7.674" "4H"  "29.296" "7.674" "5H"  "29.103" 
[15] "7.106" "6H"  "32.520" "18.377" 

上面給什麼要求,但你可能還需要重塑是爲一個矩陣,

m <- matrix(res, ncol = 3, byrow = TRUE) 

或data.frame,

data.frame(V1 = m[, 1], V2 = as.numeric(m[,2]), V3 = as.numeric(m[,3])) 
+0

+1比我的更好:) – 2014-10-17 22:37:28

+0

這裏是文件,https://drive.google.com/file/d/0B2RulP80ivJaR0NVV1ZLRlpxVDA/view?usp=sharing應用代碼不起作用,因爲其他事情之前的'行動部分「正在接受。這個信息的獨特部分是「GIAO CHEMICAL SHIELDING TENSOR(PPM):」和「.....用NMR屏蔽.....」 – user1945827 2014-10-18 08:05:00

+0

@ G.Grothendieck我想我可以創建一個從較大的文件更小的文件並應用上面給出的解決方案? – user1945827 2014-10-18 09:04:43

1

你也可以這樣做:

library(stringr) 

lines <- readLines("myfile.txt") #read the .txt file. 

提取物,然後在每行的開頭字母圓括號內的數字或數字後面的空間。你可以使用正則表達式lookbehind來提取括號內的內容。 (?<=\\() +[0-9.+] - 斷言(先於空格前跟隨數字,點。

val1 <- na.omit(str_trim(str_extract(lines, perl("(?<=\\() +[0-9.]+|^\\d+ [A-Za-z]+")))) 

創建邏輯索引,其回收到val1的長度,並提取第一,第三,第五元件....

indx <- c(TRUE, FALSE) 

使用任一indxindx!提取將val1的元素分成兩列V1V3。對於V2,請查找在EIGENVALS之前的行並提取數字。

res <- data.frame(V1=gsub(" ", "", val1[indx]), V2=as.numeric(lines[grep("EIGENVALS", 
      lines)-1]), V3=as.numeric(val1[!indx]), stringsAsFactors=FALSE) 

res 
    # V1  V2  V3 
    #1 1C 152.5897 60.5649 
    #2 2O 337.4180 114.0247 
    #3 3H 29.2964 7.6748 
    #4 4H 29.2964 7.6748 
    #5 5H 29.1030 7.1067 
    #6 6H 32.5205 18.3770