2013-09-30 37 views
2

我想從R中讀取一個巨大的csv文件,但是我遇到了麻煩,因爲假設爲字符串格式的列的元素沒有用引號分隔並且每次有新行時都會創建一個新行。我的數據由〜分隔。在R中沒有引號的read.csv行

例如,我的數據看起來類似於這樣:

a ~ b ~ c ~ d ~ e 
1 ~ name1 ~ This is a paragraph. 

This is a second paragraph. 

~ num1 ~ num2 ~ 

2 ~ name2 ~ This is an new set of paragraph. 

~ num1 ~ num2 ~ 

我希望能得到這樣的:

 

a |  b  |   c          | d  | e | 
____________________________________________________________________________________ 
1 | name1 | This is a paragraph. This is a second paragraph. | num1 | num2 | 

2 | name2 | This is a new set of paragraph.     | num1 | num2 | 

但我結束了這樣的事情醜陋:

 

a       | b |   c    | d  | e | 
__________________________________________________________________________________ 
1       | name1 | This is a paragraph. |  |  | 

This is a second paragraph |   |       |  |  | 
          | num1 |  num2 
2       | name2 | This is a new set of paragraph. | num1 | num2 | 

我試圖在read.csv中設置allowEscapes = TRUE,但那並沒有辦法。我輸入目前看起來是這樣的:

read.csv(filename, header = T, sep = '~', stringAsFactors = F, fileEncoding = "latin1", quote = "", strip.white = TRUE) 

我的下一個想法是每個〜之後插入一個報價,但我希望,看看是否有更好的方法。

任何幫助,將不勝感激。

+2

歡迎來到SO。請提供樣本數據 – Metrics

+0

每行以'〜'結尾,對嗎? – zero323

+0

@Metrics:我無法真正提供樣本數據,因爲1)它很大而且雜亂,2)我通過我的主管的數據庫獲取它,並且無法真正複製和粘貼數據。但是這個例子應該接近數據 – samuraiexe

回答

3

事情是這樣的,例如:

ll = readLines(textConnection('a ~ b ~ c ~ d ~ e 
1 ~ name1 ~ This is a paragraph. 
This is a second paragraph. 
~ num1 ~ num2 ~ 
2 ~ name2 ~ This is an new set of paragraph. 
~ num1 ~ num2 ~')) 
## each line begin with a numeric followed by a space 
## I use this pattern to sperate lines 
llines <- split(ll[-1],cumsum(grepl('^[0-9] ',ll[-1]))) 
## add the header to the splitted and concatenated lines 
read.table(text=unlist(c(ll[1],lapply(llines,paste,collapse=''))), 
      sep='~',header=TRUE) 


     a             b  c  d e 
1 name1 This is a paragraph. This is a second paragraph. num1 num2 NA 
2 name2     This is an new set of paragraph. num1 num2 NA 
+0

結尾謝謝,我明天會試試這個方法,並告訴你它是如何工作的,看看我的主管如何關閉她的電腦一天,所以我可以無法訪問數據。 – samuraiexe

+0

「當我運行我必須解析的文檔的一小部分時」我得到以下錯誤:列名稱多於列名稱 – samuraiexe

0

當我看到這是一個文本處理的問題,我決定Python中會容易得多。道歉,如果你不熟悉或沒有獲得它:

import csv 

all_rows = [] 
with open('tilded_csv.txt') as in_file: 
    header_line = next(in_file) 
    header = header_line.strip().split('~') 
    current_record = [] 
    for line in in_file: 
     # Assume that a number at the start of a line 
     # signals a new record 
     if line[0].isdigit(): 
      new_record = line.strip() 
      if current_record: 
       all_rows.append(current_record.split('~')) 
      current_record = line.strip() 
     else: 
      current_record += line.strip() 
# Add the last record 
all_rows.append(current_record.split('~')) 

with open('standard_csv.csv', 'w') as out_file: 
    out_csv = csv.writer(out_file, dialect='excel') 
    out_csv.writerow(header) 
    for row in all_rows: 
     out_csv.writerow(row) 
+0

其實我的首選語言是python,但我已經導入了其他需要導出到數據庫的文件( postgresql)使用R,所以我想我應該堅持使用標準語言來完成這項任務。最糟糕的情況是使用python。但謝謝你的提示。 – samuraiexe

2

這裏是R中依賴於(1)~是不會出現在任何一個真正的分隔符的方法你的段落和(2)~出現在每個記錄的末尾。

但首先,一些樣本數據(以其他人也可以重現您的問題的方式)。

cat("a ~ b ~ c ~ d ~ e", 
    "1 ~ name1 ~ This is a paragraph.", 
    "", 
    "This is a second paragraph.", 
    "", 
    "~ num1 ~ num2 ~", 
    "", 
    "2 ~ name2 ~ This is an new set of paragraph.", 
    "", 
    "~ num1 ~ num2 ~", sep = "\n", file = "test.txt") 

我們將與readLines開始得到的數據,我們還可以在標題行的末尾添加~

x <- readLines("test.txt") 
x[1] <- paste(x[1], "~") ## Add a ~ at the end of the first line 

現在,我們paste一切都變成一個漂亮的長字符串。

y <- paste(x, collapse = " ") 

使用scan快速「讀」的數據再次但是,而是採用了file說法,我們將使用text參數,是指我們剛創建的「Y」的對象。由於最後一行以~結尾,最後還會有一個額外的"",我們將在繼續之前刪除它。

z <- scan(text = y, what = character(), sep = "~", strip.white = TRUE) 
# Read 16 items 
z <- z[-length(z)] 

因爲我們現在有一個特徵向量,我們可以很容易地將它轉換爲一個matrix,然後到data.frame。我們知道colnames是前5個值,因此我們將在創建matrix時刪除這些值,並將它們重新插入爲data.frame的名稱。

df <- setNames(data.frame(
    matrix(z[6:length(z)], ncol = 5, byrow = TRUE)), z[1:5]) 
df 
# a  b             c d e 
# 1 1 name1 This is a paragraph. This is a second paragraph. num1 num2 
# 2 2 name2     This is an new set of paragraph. num1 num2 
+0

哇。 +1。這太棒了。 :-0 –