2015-05-20 39 views
10

我使用R處理人口普查數據,該數據使用真正長的數字GEOID來標識地理區域。我面臨的問題是使用write_csv(來自readr包)編寫處理的數據時,它正在以科學記數法編寫這些GEOID。有沒有辦法解決這個問題?readr:關閉write_csv中的科學記數法

注意:通過將scipen選項設置爲足夠大的值,我可以在R控制檯上切換科學記數法顯示。但是這個設置似乎沒有擴展到readr庫。

這裏是一個玩具數據集:

library(dplyr) 
library(readr) # which is the package with write_csv 
(tbl_df(data.frame(GEOID = seq(from=60150001022000, to=60150001022005, 1)))) 
Source: local data frame [6 x 1] 

      GEOID 
1 60150001022000 
2 60150001022001 
3 60150001022002 
4 60150001022003 
5 60150001022004 
6 60150001022005 

write_csv((tbl_df(data.frame(GEOID = seq(from=60150001022000, to=60150001022005, 1)))), "test.csv") 

這是我目前得到。我正在尋找一種方式來獲得同樣號碼的上面:

GEOID 
6.02E+13 
6.02E+13 
6.02E+13 
6.02E+13 
6.02E+13 
6.02E+13 
+0

你能準備一個小的[可重現的例子](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)來說明問題嗎?你確定你想把它們當作數值嗎?也許將它們轉換爲字符/因子值? – MrFlick

+0

我想繼續使用數字類型。知道如何抑制文件寫入的科學記數法是很好的。 – sriramn

回答

1

我會建議你使用

write.csv((tbl_df(data.frame(GEOID = seq(from=60150001022000, to=60150001022005, 1)))), "test.csv") 

代替

write_csv((tbl_df(data.frame(GEOID = seq(from=60150001022000, to=60150001022005, 1)))), "test.csv") 

如果我打開test.csv它打開Excel中的文件。 Excel將其變成科學記數法。 當我用鼠標右鍵單擊並用記事本打開它看起來不錯,我看到沒有科學記數法的原始數字。

+0

謝謝!我正在嘗試遷移到'readr'軟件包,並希望瞭解如何在該庫中完成它。 – sriramn

3

它可能會使用更安全字符值:

X <- tbl_df(data.frame(GEOID = as.character(seq(from=60150001022000, to=60150001022005)))) 

write_csv(X, "test.csv") 

這有點諷刺意味的是write_csv功能確實迫使一些它的輸出字符值,而不是數字列。只有當列通過is.object測試時纔會被強制執行。似乎沒有切換投擲,這將保持最大的精度。 write.table及其後代write.csv功能有幾個開關,可以抑制報價和其他設置,允許剪裁輸出,但write_csv幾乎沒有。

你可以欺騙write_csv,使其認爲數值列是更復雜的東西,這確實會導致as.character輸出,儘管帶有引號。

class(X[[1]])<- c("num", "numeric") 
vapply(X, is.object, logical(1)) 
#GEOID 
# TRUE 

write_csv(X, "") 
#[1] #"\"GEOID\"\n\"60150001022000\"\n\"60150001022001\"\n\"60150001022002\"\n\"60150001022003\"\n\"60150001022004\"\n\"60150001022005\"\n" 

作爲最佳實踐的一個問題,我不同意你堅持認爲變量保持數字的選擇。對於對象而言,可以應用於該存儲模式的暴力太多。對於ID變量,您不需要任何算術運算。

+0

謝謝。但我想知道是否有方法來關閉數字類型的行爲? – sriramn

1

使用bit64,它是向量S3級64位整數

library(dplyr) 
library(readr) 
options(digits = 22) 
tbl_df <- data.frame(GEOID = seq(from=60150001022000, to=60150001022005, 1)) 
> tbl_df 
      GEOID 
1 60150001022000 
2 60150001022001 
3 60150001022002 
4 60150001022003 
5 60150001022004 
6 60150001022005 

library(bit64) 
tbl_df$GEOID <- as.integer64(tbl_df$GEOID) 
write_csv(tbl_df,'test.csv') 

如果R中再次讀取該數據,它將分配正確的數據類型。

dfr <- read_csv('test.csv') 
> dfr 
Source: local data frame [6 x 1] 

      GEOID 
1 60150001022000 
2 60150001022001 
3 60150001022002 
4 60150001022003 
5 60150001022004 
6 60150001022005 

> str(tbl_df) 
'data.frame': 6 obs. of 1 variable: 
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 6 obs. of 1 variable: 
$ GEOID: num 6.02e+13 6.02e+13 6.02e+13 6.02e+13 6.02e+13 ... 

希望這會有所幫助。我在文本編輯器中打開了csv,數字在它們周圍「」。但它仍然有效。

3

我寧可建議重新編碼這樣的列鍵入int,因爲如果這樣write_*將不再使用科學數字編碼。把所有數字列在一個通(例如如果你正在使用一個計數矩陣處理),你可以這樣做:

require(dplyr)  
tbl_df = mutate_if(tbl_df, is.numeric, as.integer) 
4

我寫了一個pull request一個補丁,以提高科學記數法的write_csv控制。

有了這個補丁,你可能會有一個int_use_scientific=FALSE參數在write_csv這將解決您的問題。希望它最終會被合併。