2015-04-07 39 views
13

是否有fread由此可變的class是由在讀取的數據設置爲模仿read.table行爲的方式。防止柱級推理中的fread()

我有一個數字數據主要數據下面有幾條評論。當我使用fread來讀取數據時,列被轉換爲字符。但是,通過將nrow設置爲read.table`,我可以阻止此行爲。這是可能的fread。 (我不希望修改原始數據或修改副本)。由於

一個例子

d <- data.frame(x=c(1:100, NA, NA, "fff"), y=c(1:100, NA,NA,NA)) 
write.csv(d, "test.csv", row.names=F) 

in_d <- read.csv("test.csv", nrow=100, header=T) 
in_dt <- data.table::fread("test.csv", nrow=100) 

將會產生

> str(in_d) 
'data.frame': 100 obs. of 2 variables: 
$ x: int 1 2 3 4 5 6 7 8 9 10 ... 
$ y: int 1 2 3 4 5 6 7 8 9 10 ... 
> str(in_dt) 
Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
$ x: chr "1" "2" "3" "4" ... 
$ y: int 1 2 3 4 5 6 7 8 9 10 ... 
- attr(*, ".internal.selfref")=<externalptr> 

作爲一種變通方法,我想我將能夠使用read.table在一行閱讀,獲取類,並設置colClasses,但我誤解了。

cl <- read.csv("test.csv", nrow=1, header=T) 
cols <- unname(sapply(cl, class)) 
in_dt <- data.table::fread("test.csv", nrow=100, colClasses=cols) 
str(in_dt) 

使用Windows8.1 ř版本3.1.2(2014年10月31日) 平臺:x86_64的-W64-的mingw32/64(64位)

+3

聽起來像一個合理的計劃,但後來我實際上閱讀幫助頁面:「如果colClasses請求,fread只會將列升級到更高的類型,它不會將列降級爲更低的類型,因爲會導致NAs。如果您真的需要丟失數據,則必須自己強制這些列。「看來,甚至限制讀取5行失敗。我想我記得colClasses機制是一個相當新的增加,所以也許你應該提交一個功能請求。馬修和阿倫往往非常寬容。 –

+2

當然,必須有一個DT策略來強制所有列爲數字?將'.SDcols'設置爲合適的矢量,如下所示:'DT [,.SD:= lapply(.SDcols,as.numeric),.SDcols = vec]'。我不是一個DT用戶,但我確信有一種最小類型的方法,我懷疑你可以在SO答案中找到它。 –

+0

@BondedDust;我也不是一個DT用戶,它的just read.table與我的數據相比,具有(更嚴重的)問題。我看看SO。謝謝 – user2957945

回答

17

選項1:使用系統命令

fread()允許在第一個參數中使用系統命令。我們可以使用它來刪除文件第一列中的引號。

indt <- data.table::fread("cat test.csv | tr -d '\"'", nrows = 100) 
str(indt) 
# Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
# $ x: int 1 2 3 4 5 6 7 8 9 10 ... 
# $ y: int 1 2 3 4 5 6 7 8 9 10 ... 
# - attr(*, ".internal.selfref")=<externalptr> 

的系統命令cat test.csv | tr -d '\"'解釋:

  • cat test.csv讀取文件到標準輸出
  • |是一個管,使用前一命令的輸出作爲輸入的下一個命令
  • tr -d '\"'刪除(-d

選項2從當前輸入雙引號('\"')的所有出現:讀

由於選項1後強制似乎並不奏效您的系統上,另一可能會像你那樣讀取文件,但將x列轉換爲type.convert()

library(data.table) 
indt2 <- fread("test.csv", nrows = 100)[, x := type.convert(x)] 
str(indt2) 
# Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
# $ x: int 1 2 3 4 5 6 7 8 9 10 ... 
# $ y: int 1 2 3 4 5 6 7 8 9 10 ... 
# - attr(*, ".internal.selfref")=<externalptr> 

附註:我通常喜歡使用type.convert()as.numeric()避免在某些情況下觸發警告「受到脅迫介紹來港」。例如,

x <- c("1", "4", "NA", "6") 
as.numeric(x) 
# [1] 1 4 NA 6 
# Warning message: 
# NAs introduced by coercion 
type.convert(x) 
# [1] 1 4 NA 6 

但是當然你也可以使用as.numeric()


注:這個答案假定data.table dev v1.9.5

+0

感謝Richard,但是,這會在我的系統上引發錯誤。我正在使用Windows 8.1 – user2957945

+0

感謝您的額外信息。我已經在Windows上安裝了開發版本,但同樣的錯誤(作品,在Linux上有有用的警告)。你能解釋一下系統調用命令嗎? – user2957945

+1

@ user2957945 - 好吧,知道了。我添加了第二個應該足夠高效的選項 –

-2

好了,客戶abusing CSV format故意寫出來後串行一個整數列,但不啓動與comment.char那些行(#) 。

然後你以某種方式期望你可以覆蓋fread()的類型推斷來讀取那些整數,通過使用nrow試圖限制它看到整數行。 read.csv(..., nrow)會接受這個,但fread()總是使用所有行進行類型推斷(不僅僅是nrow, skip, header指定的行),即使它們以comment.char(這是一個bug)開頭。

  1. 聽起來像濫用CSV。您的評論行應預先加上#
  2. 是的,fread()需要修正/增強以忽略類型推斷的註釋行。
  3. 現在,你可以用fread()通過後處理的數據表中讀取的解決辦法
  4. 這是值得商榷的fread()是否應該改變,以支持你想要的行爲:使用NROWS來限制被暴露於類型推斷。它可能會修復你的(非常獨特的)案例並破壞其他一些案例。

我不明白爲什麼你(編輯:客戶)不能寫入您的意見,以一個單獨的.txt/README /數據字典文件陪.csv。使用單獨的數據字典文件的做法已相當成熟。 我從來沒有見過有人這樣做到CSV文件。至少將評論移動到標題,而不是頁腳。

+0

csv沒有多行標題。它在文件底部有不需要的東西 –

+0

好的,然後尾隨(串)註釋行,沒有任何前導'#'。你爲什麼不把它們手動追加到write.csv? – smci

+0

這不是我的問題,但我猜測OP已經有了這個文件,只是用'write.csv()'來創建一個例子。 –