我有很多大型csv文件(几MB),有很多数字和时间,所有值都没有引号存储,并用分号分隔。数字用冒号编码,用于十进制分隔符。时间编码为hh:mm:ss。缺少许多值,它们被编码为大小为零的字符串(不是“NA”)。
我需要将表示数字的字符串转换为数字,将时间转换为某些数字表示,以便进行简单的算术运算。 AFAIK R中的默认日期/时间表示非常笨重,我系统上的POSIXct对象长312个字节。
我使用这样的代码:
library(chron) #For chron function
library(plyr)
string2time<-function(f)
{
if(is.na(f))
{
return(NA)
}
if(f==''){
return(NA)
}
n<-as.numeric(f)
if(is.na(n))
{
ans<-n
try(ans<-chron(times.=f),
silent=TRUE)
return(as.numeric(ans))
}
return(n)
}
interpreteCSV<-function(filename,parallel)
{
data<-read.csv2(filename)
data.fix<-t(laply(data,function(x) {aaply(as.character(x),1,string2time)},.parallel=parallel))
return(data.fix)
}
问题是该功能似乎非常低效。
我知道,这个函数看起来很笨拙,但它是唯一一个与缺失值一起使用的函数。如果我写了两个函数,也许我可以加快一点:一个用于数字列,另一个用于时间列。但有些东西告诉我,我在这里缺少一些基本的东西,这就是为什么我要求你提供一些灵感。
以下是摘要摘录:
> ?Rprof
> summaryRprof(filename="/tmp/temp/rprof.out")
$by.self
self.time self.pct total.time total.pct
".Call" 0.30 93.75 0.30 93.75
"getIterVal.containeriter" 0.02 6.25 0.02 6.25
$by.total
total.time total.pct self.time self.pct
"<Anonymous>" 0.32 100.00 0.00 0.00
"a_ply" 0.32 100.00 0.00 0.00
"%dopar%" 0.32 100.00 0.00 0.00
"l_ply" 0.32 100.00 0.00 0.00
"prepare.rds.from.csv" 0.32 100.00 0.00 0.00
".Call" 0.30 93.75 0.30 93.75
"mclapply" 0.30 93.75 0.00 0.00
"FUN" 0.16 50.00 0.00 0.00
"lapply" 0.16 50.00 0.00 0.00
"selectChildren" 0.16 50.00 0.00 0.00
csv的示例行看起来像那样(不包括标题)。文件中有几千个这样的行:
1;XAD-01;m;wn;18,00;6;7;6;60;;;;15:10:11.8;;2,73;;16,56;;15:10:19.4;;15:10:11.8;;15:10:23.9;;15:10:19.4;;15:10:28.6;;0;;0;;0;;0;;15:10:06.0;;59,70;;15:10:36.6;;-1,47;;617;;0;;3,65;;29,96;;15:10:33.4;;15,97;;15:10:33.4;;4,43;5;12;4;30;8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
答案 0 :(得分:1)
我们假设您知道哪些列号需要转换。进一步假设这组列位于名为cols.to,convert
:
cols.to.convert <- grep( "\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}", dfrm[1,])
cols.to.convert
# [1] 13 19 21 23 25 27 37 41 53 57
dfrm[cols.to.convert] <- lapply(dfrm[cols.to.convert], as.POSIXct, format="%H:%M:%S")
# all now POSIXct class.
lapply(dfrm[cols.to.convert], class)
请注意,R POSIXct
向量将同时包含日期和时间,默认情况下,从仅时间格式转换将返回日期时间与今天的日期:
> dfrm$V57
[1] "2014-01-12 15:10:33 PST"
然后对于NA转换,这应该是相当有效的:
is.na(dfrm) <- dfrm = =""