我正在导入一个非常大的固定宽度数据集到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速度的解决办法。
非常感谢您的帮助。
发布于 2022-05-03 15:54:15
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(\"%08d\",$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发布于 2022-05-03 15:13:49
这些格式在总体上是很糟糕的,但是不管怎么说,readr中的任何东西都不适合你,因为一个月中有1到2位数字。我建议将该列导入为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。在这种情况下,应该分别是0和1。如果您有长度6的字符串,这可能是一个问题,只有您知道是否有问题。strrep("0", ..)根据需要重复0字符串多次,包括生成""的strrep("0", 0) (没有零)。pmax(.., 0)是一个防御性的程序员,如果里面有一个长度-9的字符串,我们不能做strrep("0", -1),我们想防止它变成负值。paste0(.., vec)来做实际的填充.从此,所有字符串都应该标准化,并能够使用"%d%m%Y"进行转换。
发布于 2022-05-03 15:24:19
如果您有整数数据,您可以让pad丢失的0重新打开。
as.Date(sprintf("%08d", vec), format = "%d%m%Y")
# [1] "1985-03-21" "1985-03-01"https://stackoverflow.com/questions/72101496
复制相似问题