我正在將一個非常大的固定寬度資料集匯入 R 并希望使用 vroom 以獲得更好的速度。但是,此資料集中的日期為 7 位或 8 位數字格式,具體取決于月份中的日期是 1 位還是 2 位(示例如下)。
#8 digit date (1985-03-21):
# 21031985
#7 digit date (1985-03-01):
# 1031985
col_date(format = )
我看不出有任何方法可以像通常那樣使用這種格式。制作一個將這些 7/8 位數字轉換為日期的函式很容易,但這樣做意味著將匯入的資料具體化并消除 vroom 提供的速度優勢。
我正在尋找一種讓 vroom 自己解釋這些數字的方法,或者一種不犧牲 vroom 速度的解決方法。
非常感謝這里的任何幫助。
uj5u.com熱心網友回復:
這些格式通常很糟糕,但無論如何,readr
由于每月的 1 或 2 位數字,我認為沒有任何內容適合您。我建議在 as 中匯入閱讀該列col_character
,然后使用
vec <- c("21031985", "1031985")
as.Date(paste0(strrep("0", pmax(8 - nchar(vec), 0)), vec), format = "%d%m%Y")
# [1] "1985-03-21" "1985-03-01"
快速演練:
8 - nchar(vec)
0
告訴我們需要在每個字串的左側填充多少個 s。在這種情況下,它應該分別是0
和1
。如果您有長度為 6 的字串,這可能是個問題,只有您知道這是否是個問題。strrep("0", ..)
根據需要重復0
字串多次,包括strrep("0", 0)
產生""
(無零)。pmax(.., 0)
是防御性程式員,如果那里有一個長度為 9 的字串,我們不能這樣做strrep("0", -1)
,我們希望它不會變成負數。paste0(.., vec)
做實際的填充。
從那里開始,所有字串都應該被規范化并且能夠使用"%d%m%Y"
.
uj5u.com熱心網友回復:
Vroom 可以使用管道作為輸入。這意味著您可以使用諸如awk
修復格式之類的工具(例如,使其始終為 8 位,這很容易使用sprintf
)。這樣,您仍然可以從 vroom 流式傳輸檔案中受益。你甚至可以使用 R - 但如果你追求性能,你需要一些可以處理檔案流的東西,并且最好是輕量級的。
我使用了一個測驗檔案test.csv
:
id,date,text
1,1022020,some
2,12042020,more
3,2012020,text
我可以通過以下方式閱讀它(當然需要針對您的資料調整 awk 呼叫 - 但基本上如果您只需要調整列$2
表示第二列,則','
指定分隔符):
vroom(pipe("awk -F ',' 'BEGIN{OFS=\",\"}; NR==1{print}; NR!=1 {$2=sprintf(\"d\",$2);print;}' test.csv"),
col_types=cols(date=col_date(format='%d%m%Y'))
)
給予
# A tibble: 3 × 3
id date text
<int> <date> <chr>
1 1 2020-02-01 some
2 2 2020-04-12 more
3 3 2020-01-02 text
uj5u.com熱心網友回復:
如果您有整數資料,您可以將丟失0
的 s 重新填充。
as.Date(sprintf("d", vec), format = "%d%m%Y")
# [1] "1985-03-21" "1985-03-01"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/470818.html