2014-10-16 50 views
0

我有一個數據集,每行有40,000多行,列數不相等。我遇到的問題是,每行末尾的每個值都屬於同一列,但最終會在許多不同列中跳水。R每行正確導入不等數量的列

所以我的問題是:是否有一個簡單的方法,要求每行的最終值放在同一列?

標題有: C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14

BAC0004 | ACR3 | TR | B5LX01 | B5LX01_CAMJU ACR3 GN = ACR3 PE = 4 SV = 1個多藥耐藥
BAC0017 | ADEI | TR | Q2FD95 | Q2FD95_ACIBA ADEI GN = ADEI PE = 4 SV = 1的預測蛋白 BAC0001 | ABEM | TR | Q5FAM9 | Q5FAM9_ACIBA多藥外排泵ABEM GN = ABEM PE = 4 SV = 2多藥耐藥蛋白

當前導入如下所示:

c1         c2  c3  c4  c5  c6  c7 c8 c9 
BAC0004|acr3|tr|B5LX01|B5LX01_CAMJU Acr3  GN=acr3 PE=4 SV=1 multidrug resistance 
BAC0017|adeI|tr|Q2FD95|Q2FD95_ACIBA AdeI  GN=adeI PE=4 SV=1 predicted protein 
BAC0001|abeM|tr|Q5FAM9|Q5FAM9_ACIBA Multidrug efflux pump AbeM GN=abeM PE=4 SV=2 multidrug efflux pump 

如果有的話,我想它看起來像這樣:

c1         c2  c3  c4  c5 c6  c7 c8 c9 
BAC0004|acr3|tr|B5LX01|B5LX01_CAMJU Acr3  GN=acr3 PE=4 SV=1 NA  NA NA multidrug resistance 
BAC0017|adeI|tr|Q2FD95|Q2FD95_ACIBA AdeI  GN=adeI PE=4 SV=1 NA  NA NA predicted protein 
BAC0001|abeM|tr|Q5FAM9|Q5FAM9_ACIBA Multidrug efflux pump AbeM GN=abeM PE=4 SV=2 multidrug efflux pump 

,但最好是這樣的:

c1               c2 c3  c4 c5 c6 
BAC0004|acr3|tr|B5LX01|B5LX01_CAMJU      Acr3 GN=acr3 PE=4 SV=1 multidrug resistance 
BAC0017|adeI|tr|Q2FD95|Q2FD95_ACIBA      AdeI GN=adeI PE=4 SV=1 predicted protein 
BAC0001|abeM|tr|Q5FAM9|Q5FAM9_ACIBA Multidrug efflux pump AbeM GN=abeM PE=4 SV=2 multidrug efflux pump 

這是3號線在此引起的所有問題 - 我會如果將名稱保留爲一個長字符串並且不添加這3個額外的列,但是我真正想要的是名稱(c1)和描述(最後一個值),我願意以這種方式處理它別無他法。

但我只是在想,也許有一種告訴R如何分割字符串的方法 - 也許這樣,所有在「GN = *」值之後的值都被放入3個單獨的列中。我不知道什麼是最好的。謝謝你的幫助。

+1

你能發表一個小樣本來說明你的問題以及你想得到什麼嗎? – ilir 2014-10-16 14:49:19

+0

肯定 - 會做。 – 2014-10-16 14:50:01

+0

如果你在'read.table()'中指定'fill = TRUE',它會有幫助嗎? – konvas 2014-10-16 14:59:12

回答

2

這是一個非常混亂的文件格式。如果您將字段與製表符分開或者可以在行中輕鬆找到,會更好。作爲一個人,我很難猜測在哪裏休息,所以我不感到驚訝read.table有麻煩。

你可以用正則表達式解析這些字符串。類似於

#lines <- readLines("filename.txt") 
lines <- c("BAC0004|acr3|tr|B5LX01|B5LX01_CAMJU Acr3 GN=acr3 PE=4 SV=1 multidrug resistance", 
"BAC0017|adeI|tr|Q2FD95|Q2FD95_ACIBA AdeI GN=adeI PE=4 SV=1 predicted protein","BAC0001|abeM|tr|Q5FAM9|Q5FAM9_ACIBA Multidrug efflux pump AbeM GN=abeM PE=4 SV=2 multidrug resistance protein") 

m <-regexpr("(.*) (\\w+) (GN=\\S+) (PE=\\S+) (SV=\\S+) (.*)", lines, perl=T) 

這將報告每個列的開始位置和長度。您可以使用子字符串提取值,或者可以使用幫助函數,如regcapturedmatches。如果我們把字段之間的結果和propertly插入選項卡,然後我們可以使用read.table()做出data.frame

read.table(text=sapply(regcapturedmatches(lines,m), function(x) paste(x, collapse="\t")), sep="\t", as.is=T) 

這給

              V1 V2  V3 V4 V5       V6 
1      BAC0004|acr3|tr|B5LX01|B5LX01_CAMJU Acr3 GN=acr3 PE=4 SV=1   multidrug resistance 
2      BAC0017|adeI|tr|Q2FD95|Q2FD95_ACIBA AdeI GN=adeI PE=4 SV=1   predicted protein 
3 BAC0001|abeM|tr|Q5FAM9|Q5FAM9_ACIBA Multidrug efflux pump AbeM GN=abeM PE=4 SV=2 multidrug resistance protein 

這似乎符合您期望的結果。

+0

太棒了!這對三條線是有效的,在我沒有包括的行中有更多的列,但是使用它正在工作的相同方法。但是,該文件是40,000的事實呢?我可以使用readLines(文件),但對於< - c(....)行,我會放什麼? – 2014-10-16 17:59:02

+0

'readLines'應該返回一個字符數組,以便您可以直接使用結果,只需將其分配給變量'lines'即可。 – MrFlick 2014-10-16 22:58:38