2011-10-25 50 views
8

我可以使用read.csv或read.csv2將數據讀入R.但是我遇到的問題是我的分隔符是多字節字符串而不是單個字符。我該如何處理這個問題?如何使用多字節分隔符將文本文件讀入GNU R?

+1

什麼是你的多字節字符串? – jthetzel

+0

我相信,如果你看看更一般的read.table()和sep參數,你可以使用一個多字節的字符串。 – mweylandt

+0

@mweylandt我認爲'read.table()'''sep'只接受單個字節(對於scan()是相同的)。 – jthetzel

回答

9

提供示例數據將有所幫助。但是,您可能可以根據需要調整以下內容。

我創建的示例性數據文件,該文件是包含以下內容的只是一個文本文件:

1sep2sep3 
1sep2sep3 
1sep2sep3 
1sep2sep3 
1sep2sep3 
1sep2sep3 
1sep2sep3 

我保存爲「test.csv」。分隔字符是'sep'字符串。我認爲read.csv()使用scan(),它只接受sep的單個字符。爲了解決它,考慮以下因素:

dat <- readLines('test.csv') 
dat <- gsub("sep", " ", dat) 
dat <- textConnection(dat) 
dat <- read.table(dat) 

readLines()只是讀取線gsub替代了多字符字符串分離 - 對單個' ',或任何方便您的數據。然後textConnection()read.data()方便地讀取所有內容。對於較小的數據集,這應該沒問題。如果數據量非常大,請考慮使用AWK等預處理來替換多字符分隔字符串。以上是從http://tolstoy.newcastle.edu.au/R/e4/help/08/04/9296.html

更新 關於你的評論,如果你在你的數據空間,使用不同的替代隔膜。考慮更改test.csv到:

1sep2 2sep3 
1sep2 2sep3 
1sep2 2sep3 
1sep2 2sep3 
1sep2 2sep3 
1sep2 2sep3 
1sep2 2sep3 

然後,用下面的函數:

readMulti <- function(x, sep, replace, as.is = T) 
{ 
    dat <- readLines(x) 
    dat <- gsub(sep, replace, dat) 
    dat <- textConnection(dat) 
    dat <- read.table(dat, sep = replace, as.is = as.is) 

    return(dat) 
} 

嘗試:

readMulti('test.csv', sep = "sep", replace = "\t", as.is = T) 

在這裏,你替換選項卡(\t)原來的分隔符。 as.is傳遞給read.table()以防止讀取字符串是因素,但這是你的電話。如果您的數據中更復雜的空白,你可能會發現quote參數與AWK,Perl等read.table()幫助,或預處理

一些與crippledlambda的strsplit()類似的是中等規模的數據最有可能的等價物。如果性能成爲問題,請嘗試兩種方法,看看哪些適合您。

+0

read.table將得到相同的錯誤信息。jthetzel的建議聽起來很不錯。事實上,我已經利用awk來處理原始數據,然後再在R中讀取它。但是這裏的問題是我們如何在gsub之後處理新分隔字符中的字符(也就是說,我們有一個' '在示例代碼中的值內)。 – RobinMin

+0

@RobinMin在上面的每個更新中嘗試使用不同的替換分隔符。 – jthetzel

3

在這種情況下,您可以用您的文件名替換textConnection(txt),但基本上可以在strsplit附近構建代碼或函數。在這裏,我假設你有一個標題行,但你當然可以給定義header論證和推廣基於下面的函數創建您的數據幀:

> read.multisep <- function(File,sep) { 
+ Lines <- readLines(File) 
+ Matrix <- do.call(rbind,strsplit(Lines,sep,fixed=TRUE)) 
+ DataFrame <- structure(data.frame(Matrix[-1,]),names=Matrix[1,]) ## assuming header is present 
+ DataFrame[] <- lapply(DataFrame,type.convert)     ## automatically convert modes 
+ DataFrame 
+ } 
> 
> example <- "a#*&b#*&c 
+ 1#*&2#*&3 
+ 4#*&5#*&6" 
> 
> read.multisep(textConnection(example),sep="#*&") 
    a b c 
1 1 2 3 
2 4 5 6 
+0

read.multisep適合我〜!謝謝@ jthetzel – RobinMin

相關問題