2012-03-15 44 views
2

我期待讀.tps文件到R.讀一.tps形態測量文件爲R

示例文件現已在:

example file

實際的文件我試圖讀入R顯然有更多的個人/ ID(> 1000)

.tps文件格式由TPSDIG生成。

http://life.bio.sunysb.edu/morph/

該文件是ANSI純文本文件。

該文件包含X和Y座標和樣本信息如下。

主要困難在於標本在屬性數量上有所不同(例如,一些有4個,有些有6個LM界標,有些有2條曲線,其他沒有,因此沒有關聯點)。

我已經嘗試使用for循環和read.table,但無法找到解決不同數量屬性的方法。

文件開始

LM=3 
1 1 
2 2 
3 3 
CURVES=2 
POINTS=2 
1 1 
2 2 
POINTS=2 
1 1 
2 2 
IMAGE=COMPLETE/FILE/PATH/IMAGE 
ID=1 
SCALE=1 
LM=3 
1 1 
2 2 
3 3 
CURVES=2 
... 

例虛設碼,如果所有的標本有屬性的數量相等,工程實例。

i<-1 
landmarks<-NULL 
while(i < 4321){ 

    print(i) 

    landmarks.temp<-read.table(file="filepath", sep=" ", header=F, skip=i, nrows=12, col.names=c("X", "Y")) 
    i<-i+13 
    landmarks.temp$ID<-read.table(file="filepath", sep=c(" "), header=F, skip=i, nrows=1, as.is=T)[1,1] 
    i<-i+1 
    landmarks.temp$scale<-read.table(file="filepath", sep=c(" "), header=F, skip=i, nrows=1, as.is=T)[1,1] 
    i<-i+2 

    landmarks<-rbind(landmarks, landmarks.temp) 

    print(unique(landmarks.temp$ID)) 
} 
+0

我想你會想用'scan'和/或'readLines'來實現更好的控制... – 2012-03-15 23:09:30

+0

謝謝Bolker教授, – 2012-03-16 12:34:44

+0

謝謝Bolker教授,然而read.table似乎提供了作爲'掃描'(它是一個包裝)或'readLines'具有很大的靈活性。我開始認爲我需要逐行閱讀(使用'read.table','readLines'或'scan'),併爲每行可能的值和前一行寫入條件。我正在跳躍的人可能已經完成了這項工作。 – 2012-03-16 12:42:08

回答

3

我不完全清楚你在輸出中尋找什麼。我假定一個標準的數據框架,其中X,Y,ID和Scale是變量。

試試這個功能,我扔在一起,看看它給你輸出的,你要尋找的類型:

read.tps = function(data) { 
     a = readLines(data) 
     LM = grep("LM", a) 
     ID.ind = grep("ID", a) 
     images = basename(gsub("(IMAGE=)(.*)", "\\2", a[ID.ind - 1])) 

     skip = LM 
     nrows = as.numeric(gsub("(LM=)([0-9])", "\\2", grep("LM", a, value=T))) 
     l = length(LM) 

     landmarks = vector("list", l) 

     for (i in 1:l) { 
     landmarks[i] = list(data.frame(
      read.table(file=data, header=F, skip=LM[i], 
         nrows=nrows[i], col.names=c("X", "Y")), 
      IMAGE = images[i], 
      ID = read.table(file=data, header=F, skip=ID.ind[i]-1, 
          nrows=1, sep="=", col.names="ID")[2,], 
      Scale = read.table(file=data, header=F, skip=ID.ind[i], 
           nrows=1, sep="=")[,2])) 
     } 
     do.call(rbind, landmarks) 
    } 

加載了功能後,您可以通過鍵入使用它:

read.tps("example.tps") 

其中「example.tps」是您工作目錄中.tps文件的名稱。

如果你想你的分配輸出到一個新的對象,你可以使用標準:

landmarks <- read.tps("example.tps") 
+0

太棒了! readLines和grep是我缺少的關鍵。這將解開許多未來類似的問題。 – 2012-03-17 03:23:40

+0

我不知道有多少人會喜歡這個功能,但也許你可以在github或類似的地方發佈它。 – 2012-03-17 06:54:28

+1

@ EtienneLow-Décarie,你可以看看這個函數的版本[我在Git Hub上發佈](https://gist.github.com/2062329),我在其中添加了評論,所以你可以看到究竟是如何解決你的挑戰。 – A5C1D2H2I1M1N2O1R2T1 2012-03-17 19:39:26

0

也許值得一提的是,現在有r包geomorph具有功能readland.tps()這一點。